1. 程式人生 > >事務學習--轉賬例子

事務學習--轉賬例子

package cn.taylor.dao;

import java.sql.Connection;
import java.sql.PreparedStatement;

/*
 * 學習事務最簡單的例子就是轉賬,假如張三給李四轉100塊錢,其實用兩句sql語句就可以實現,
 * 第一句是給張三賬戶減去100;第二句是給李四賬戶加上100
 * 但是如果在第一句sql語句執行之後出現錯誤,導致第二句沒有執行,就會出現張三的錢少了,
 * 而李四的錢沒加,為了避免這種情況,我們學習事務。
 * 一旦擁有了事務的原子性,事務中的操作要麼全部執行,要麼全部執行失敗。
 */
/*
 * jdbc中的事務的程式碼格式
 * try{
 * 	con.setAutoCommit(false);	//開啟事務
 * 	...
 *  ....
 *  con.commit();	//try的最後提交事務
 * }
 * catch(){
 * con.rollback();	//回滾事務,表示結束
 * }
 */
public class AccountDao {
	/*
	 * 修改時指定使用者的餘額
	 */
	public void updateBalance(Connection con,String name,double balance){
		try{
		//在jdbc中處理事務,都是通過Connection物件完成的。
			
		/*
		 * 在同一事務中所有的操作,都在使用同一個Connection物件,為了保證這一點 ,
		 * 所以要將下面程式碼修改。
		 * 改成是在方法的引數中提供Connection物件
		 */
			//Connection con =JdbcUtils.getConnection();
			String sql="update balance set balance=balance+? where name=?";
			PreparedStatement pstmt=con.prepareStatement(sql);
			
			pstmt.setDouble(1, balance);
			pstmt.setString(2, name);
			
			pstmt.executeUpdate();
			
		}catch(Exception e){
			throw new RuntimeException(e);
		}
	
		
	}

}

package cn.taylor.dao;

import java.sql.Connection;
import java.sql.SQLException;

import org.junit.Test;
/*
 * 所有對Connection的操作都在Service層進行的處理
 * 之後我們要改進這個問題,我們要把所有對Connection的操作隱藏起來,這需要使用
 * 自定義的小工具。
 */
public class Demo1 {
	public void zhuanzhang(String from,String to,double money) throws Exception{
		//對事物的操作必須使用Connection物件
		Connection con=null;
		try{
			con=JdbcUtils.getConnection();
			con.setAutoCommit(false);	//設定不要自動提交
			AccountDao dao=new AccountDao();
			
			dao.updateBalance(con, from, -money);
			dao.updateBalance(con, to, money);
			
			con.commit();
			con.close();
		}catch(Exception e){
			try{
				con.rollback();
				con.close();
			}catch(SQLException e1){}
			throw new RuntimeException(e);
			}
		}
	
	@Test
	public void fun1() throws Exception{
		zhuanzhang("zhangsan","lisi",100);
	}
	}