程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 數據庫知識 >> DB2數據庫 >> DB2教程 >> JDBC操作事務

JDBC操作事務

編輯:DB2教程

JDBC操作事務


在JDBC事務操作中,都是通過Connection完成的。

同一個事務中所有的操作,都在使用同一個Connection對象。

JDBC中的事務

Connection中與事務相關的三個方法: setAutoCommit(boolean):設置是否為自動提交事務,如果true(默認值就是true)表示自動提交,也就是每條執行的SQL語句都是一個單獨的事務,如果設置false,那麼就相當於開啟了事務了;con.setAutoCommit(false)表示開啟事務!commit():提交結束事務;con.commit();表示提交事務rollback():回滾結束事務。con.rollback();表示回滾事務

jdbc處理事務的代碼格式
try {
con.setAutoCommit(false);//開啟事務…
….
…
con.commit();//try的最後提交事務
} catch() {
con.rollback();//回滾事務
}
 

比如支付寶轉賬!張三轉1000塊到李四的賬戶,這其實需要兩條SQL語句:

給張三的賬戶減去1000元;給李四的賬戶加上1000元。 如果在第一條SQL語句執行成功後,在執行第二條SQL語句之前,程序被中斷了(可能地下光纖被挖掘機挖斷了……確實存在的哦),那麼李四的賬戶沒有加上1000元,而張三卻減去了1000元。這肯定是不行的!
你現在可能已經知道什麼是事務了吧!事務中的多個操作,要麼完全成功,要麼完全失敗!不可能存在成功一半的情況!也就是說給張三的賬戶減去1000元如果成功了,那麼給李四的賬戶加上1000元的操作也必須是成功的;否則給張三減去1000元,以及給李四加上1000元都是失敗的!

假如我們有一個表,為account,其內容為:

ID NAME BALANCE 1 zhangsan 10000 2 lisi 10000

 

 



public void transfer(boolean b) { Connection con = null; PreparedStatement pstmt = null; try { con = JdbcUtils.getConnection(); //手動提交 con.setAutoCommit(false); String sql = "update account set balance=balance+? where id=?"; pstmt = con.prepareStatement(sql); //操作 pstmt.setDouble(1, -10000);//為參數1賦值 pstmt.setInt(2, 1); //為參數2賦值 pstmt.executeUpdate(); // 在兩個操作中故意拋出異常,則事務失敗; if(b) { throw new Exception(); } pstmt.setDouble(1, 10000);//為參數1賦值 pstmt.setInt(2, 2);//為參數2賦值 pstmt.executeUpdate(); //提交事務 con.commit(); } catch(Exception e) { //回滾事務 if(con != null) { try { con.rollback(); } catch(SQLException ex) {} } throw new RuntimeException(e); } finally { //關閉 JdbcUtils.close(con, pstmt); } }
 

 


 

 

保存點

保存點是JDBC3.0的東西!需要數據庫服務器能夠支持保存點方式的回滾。校驗數據庫服務器是否支持保存點!

 

boolean b = con.getMetaData().supportsSavepoints();

 

保存點的作用是允許事務回滾到指定的保存點位置。在事務中設置好保存點,然後回滾時可以選擇回滾到指定的保存點,而不是回滾整個事務!注意,回滾到指定保存點並沒有結束事務!!!只有回滾了整個事務才算是結束事務了!
Connection類的設置保存點,以及回滾到指定保存點方法:
設置保存點:Savepoint setSavepoint();回滾到指定保存點:void rollback(Savepoint)。

    /*
     * 李四對張三說,如果你給我轉1W,我就給你轉100W。
     * ==========================================
     * 
     * 張三給李四轉1W(張三減去1W,李四加上1W)
     * 設置保存點!
     * 李四給張三轉100W(李四減去100W,張三加上100W)
     * 查看李四余額為負數,那麼回滾到保存點。
     * 提交事務
     */
    @Test
    public void fun() {
	    Connection con = null;
	    PreparedStatement pstmt = null;
	    try {
		    con = JdbcUtils.getConnection();
		    //手動提交
		    con.setAutoCommit(false);
		    String sql = "update account set balance=balance+? where name=?";
		    pstmt = con.prepareStatement(sql);
		    //操作1(張三減去1W)
		    pstmt.setDouble(1, -10000);
		    pstmt.setString(2, "zs");
		    pstmt.executeUpdate();
		    //操作2(李四加上1W)
		    pstmt.setDouble(1, 10000);
		    pstmt.setString(2, "ls");
		    pstmt.executeUpdate();
		    // 設置保存點
		    Savepoint sp = con.setSavepoint();
		    //操作3(李四減去100W)
		    pstmt.setDouble(1, -1000000);
		    pstmt.setString(2, "ls");
		    pstmt.executeUpdate();
		    //操作4(張三加上100W)
		    pstmt.setDouble(1, 1000000);
		    pstmt.setString(2, "zs");
		    pstmt.executeUpdate();
		    //操作5(查看李四余額)
		    sql = "select balance from account where name=?";
		    pstmt = con.prepareStatement(sql);
		    pstmt.setString(1, "ls");
		    ResultSet rs = pstmt.executeQuery();
		    rs.next();
		    double balance = rs.getDouble(1);
		    //如果李四余額為負數,那麼回滾到指定保存點
		    if(balance < 0) {
		    	con.rollback(sp);
		    	System.out.println("張三,你上當了!");
		    }
		    //提交事務
		    con.commit();
		} catch(Exception e) {
		    //回滾事務
		    if(con != null) {
			    try {
			    	con.rollback();
			    } catch(SQLException ex) {}
		    }
		    throw new RuntimeException(e);
	    } finally {
	    	//關閉
	    	JdbcUtils.close(con, pstmt);
	    }
    } 

 

---完---

 

 


  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved