【Java學習】JDBC事務

概述

在開發中,咱們對數據庫的多個表或對一個表的多條數據執行更新操做的時候,要保證多個更新操做要麼同時成功、要麼都不成功。這就涉及到多個更新操做的事務管理問題了。sql

例如:銀行的轉帳問題,A用戶向B用戶轉帳100元,假設A用戶和B用戶的錢都存儲在Account表中,那麼A向B轉帳就涉及同時更新Account表中的A用戶的錢和B用戶的錢,否則的話,A的錢少了,而B卻沒有收到錢,這是不容許出現的事件。數據庫

update account set money = money -100 where name = 'A';
update account set money = money + 100 where name = 'B';

事務

爲何上面的sql語句不可以實現「要麼都成功、要麼都失敗」?這是由於若是JDBC處於自動提交模式,每一個SQL語句在完成後都會提交到數據庫,也就是說在執行A扣錢(即第一條sql)語句以後,他就已經更新了數據庫,若是這個時候程序忽然崩潰,致使後面的語句沒有運行,那麼就出現了咱們說的,a扣錢了,可是b卻沒收到錢。併發

因此咱們須要考慮是否關閉自動提交而且管理本身的事務。spa

事務可以控制什麼時候更改提交併應用於數據庫。它將單個SQL語句或一組SQL語句視爲一個邏輯單元,若是任何語句失敗,整個事務將失敗。.net

如上面所說,JDBC鏈接默認是處於自動提交,咱們須要手動的打開這個功能。調用Connection對象的setAutoCommit()方法,將false傳遞給setAutoCommit(),就關閉了自動提交。也能夠創第一個布爾值true來打開它。3d

conn.setAutoCommit(false);

如今咱們知道了,想要讓多條更新語句保持原子性,首先要關閉自動提交,而後手動提交,在一個事務失敗的時候,要進行回滾。code

提交和回滾

完成更改後,若要提交更改,須要在對象上調用commit()方法:orm

conn.commit();

不然要進行回滾對象

conn.rollback();

如下實例說明了如何使用提交和回滾。blog

try{
    conn.setAutoCommit(false);
    Statement stmt = conn.createStatement();
    
    String SQL = "INSERT INTO Employees" + "VALUES (106,20,'Rita,'Tez')";
    stmt.executeUpdate(SQL);
    
    String SQL = "IMSERT IN Employees " + "VALUES (107,22,'SITA','SINGH')";
    stmt.excuteUpdate(SQL);
    
    conn.commit();

}catuch(SQLException se){
    conn.rollback();
    
}

使用保存點

新的JDBC3.0新添加了Savepoint接口提供了額外的事務控制能力。
使用Connection對象兩個方法來建立Savepoint對象。

setSavepoint(String savepointName);//定義新的保存點,返回`Savepoint`對象。
releaseSavepoint(Savepoint savepointName);//刪除保存點。參數是由上面的方法生出的對象。

這樣使用rollback(String savepointName)方法,就能夠將事務回滾到指定的保存點

try{
   //Assume a valid connection object conn
   conn.setAutoCommit(false);
   Statement stmt = conn.createStatement();

   //set a Savepoint
   Savepoint savepoint1 = conn.setSavepoint("Savepoint1");
   String SQL = "INSERT INTO Employees " +
                "VALUES (106, 24, 'Curry', 'Stephen')";
   stmt.executeUpdate(SQL);  
   //Submit a malformed SQL statement that breaks
   String SQL = "INSERTED IN Employees " +
                "VALUES (107, 32, 'Kobe', 'Bryant')";
   stmt.executeUpdate(SQL);
   // If there is no error, commit the changes.
   conn.commit();

}catch(SQLException se){
   // If there is any error.
   conn.rollback(savepoint1);
}

事務的隔離性

以上咱們說明了,如何實現一個數據要麼都成功,要麼都失敗,這個實際上是在事務中的原子性。而另外一個比較重要的就是隔離性

什麼是隔離性

所謂隔離性是指事務與事務之間的隔離,即在事務提交之間,其餘事務中與未完成的事務的數據中間狀態訪問權限,具體能夠經過設置隔離級別來進行控制。

併發事務可能出現的狀況

髒讀

一個事務讀取另外一個事務還沒有提交的數據。

clipboard.png

這個解決辦法,就是在事務進行操做的時候,禁止該事物進行讀操做。

不可從新讀

其餘事務的操做致使某一個事務兩次讀取數據不一致。

clipboard.png

幻讀

其餘事務的數據操做致使某個事務兩次讀取數據數量不一致。

參考資料

JDBC應用中的事務管理
Mysql數據庫事務在jdbc中的用法
JDBC事務和事務的隔離等級

未完待續。。。

相關文章
相關標籤/搜索