Java的JDBC事務詳解

事務的特性:

1) 原子性(atomicity):事務是數據庫的邏輯工作單位,而且是必須是原子工作單位,對於其數據修改,要麼全部執行,要麼全部不執行。

2) 一致性(consistency):事務在完成時,必須是所有的數據都保持一致狀態。在相關數據庫中,所有規則都必須應用於事務的修改,以保持所有數據的完整性。

3) 隔離性(isolation):一個事務的執行不能被其他事務所影響。

4) 持久性(durability):一個事務一旦提交,事物的操作便永久性的保存在DB中。即使此時再執行回滾操作也不能撤消所做的更改。

事務(Transaction):是併發控制的單元,是用戶定義的一個操作序列。這些操作要麼都做,要麼都不做,是一個不可分割的工作單位。通過事務,sql server 能將邏輯相關的一組操作綁定在一起,以便服務器 保持數據的完整性。事務通常是以begin transaction開始,以commit或rollback結束。Commint表示提交,即提交事務的所有操作。具體地說就是將事務中所有對數據的更新寫回到磁盤上的物理數據庫中去,事務正常結束。Rollback表示回滾,即在事務運行的過程中發生了某種故障,事務不能繼續進行,系統將事務中對數據庫的所有已完成的操作全部撤消,滾回到事務開始的狀態。

自動提交事務:每條單獨的語句都是一個事務。每個語句後都隱含一個commit。 (默認)

顯式事務:以begin transaction顯示開始,以commit或rollback結束。

隱式事務:當連接以隱式事務模式進行操作時,sql server數據庫引擎實例將在提交或回滾當前事務後自動啓動新事務。無須描述事物的開始,只需提交或回滾每個事務。但每個事務仍以commit或rollback顯式結束。連接將隱性事務模式設置爲打開之後,當數據庫引擎實例首次執行下列任何語句時,都會自動啓動一個隱式事務:alter table,insert,create,open ,delete,revoke ,drop,select, fetch ,truncate table,grant,update在發出commit或rollback語句之前,該事務將一直保持有效。在第一個事務被提交或回滾之後,下次當連接執行以上任何語句時,數據庫引擎實例都將自動啓動一個新事務。該實例將不斷地生成隱性事務鏈,直到隱性事務模式關閉爲止。

 

Java JDBC事務機制

  首先,我們來看看現有JDBC操作會給我們打來什麼重大問題,比如有一個業務:當我們修改一個信息後再去查詢這個信息,看是這是一個簡單的業務,實現起來也非常容易,但當這個業務放在多線程高併發的平臺下,問題自然就出現了,比如當我們執行了一個修改後,在執行查詢之前有一個線程也執行了修改語句,這是我們再執行查詢,看到的信息就有可能與我們修改的不同,爲了解決這一問題,我們必須引入JDBC事務機制,其實代碼實現上很簡單,一下給出一個原理實現例子供大家參考:

private Connection conn = null;  

private PreparedStatement ps = null;  

 

try {  

    conn.setAutoCommit(false);  //將自動提交設置爲false  

              

    ps.executeUpdate("修改SQL"); //執行修改操作  

    ps.executeQuery("查詢SQL");  //執行查詢操作                 

    conn.commit();      //當兩個操作成功後手動提交  

              

} catch (Exception e) {  

    conn.rollback();    //一旦其中一個操作出錯都將回滾,使兩個操作都不成功  

    e.printStackTrace();  

與事務相關的理論
1.事務(Transaction)的四個屬性(ACID)
原子性(Atomic) 對數據的修改要麼全部執行,要麼全部不執行。
一致性(Consistent) 在事務執行前後,數據狀態保持一致性。
隔離性(Isolated) 一個事務的處理不能影響另一個事務的處理。
持續性(Durable) 事務處理結束,其效果在數據庫中持久化。

2.事務併發處理可能引起的問題
髒讀(dirty read) 一個事務讀取了另一個事務尚未提交的數據,
不可重複讀(non-repeatable read) 一個事務的操作導致另一個事務前後兩次讀取到不同的數據
幻讀(phantom read) 一個事務的操作導致另一個事務前後兩次查詢的結果數據量不同。
舉例:
事務A、B併發執行時,
當A事務update後,B事務select讀取到A尚未提交的數據,此時A事務rollback,則B讀到的數據是無效的"髒"數據。
當B事務select讀取數據後,A事務update操作更改B事務select到的數據,此時B事務再次讀去該數據,發現前後兩次的數據不一樣。
當B事務select讀取數據後,A事務insert或delete了一條滿足A事務的select條件的記錄,此時B事務再次select,發現查詢到前次不存在的記錄("幻影"),或者前次的某個記錄不見了。

JDBC的事務支持
JDBC對事務的支持體現在三個方面:
1.自動提交模式(Auto-commit mode)
Connection提供了一個auto-commit的屬性來指定事務何時結束。
a.當auto-commit爲true時,當每個獨立SQL操作的執行完畢,事務立即自動提交,也就是說每個SQL操作都是一個事務。
一個獨立SQL操作什麼時候算執行完畢,JDBC規範是這樣規定的:
對數據操作語言(DML,如insert,update,delete)和數據定義語言(如create,drop),語句一執行完就視爲執行完畢。
對select語句,當與它關聯的ResultSet對象關閉時,視爲執行完畢。
對存儲過程或其他返回多個結果的語句,當與它關聯的所有ResultSet對象全部關閉,所有update count(update,delete等語句操作影響的行數)和output parameter(存儲過程的輸出參數)都已經獲取之後,視爲執行完畢。
b. 當auto-commit爲false時,每個事務都必須顯示調用commit方法進行提交,或者顯示調用rollback方法進行回滾。auto-commit默認爲true。
JDBC提供了5種不同的事務隔離級別,在Connection中進行了定義。

2.事務隔離級別(Transaction Isolation Levels)
JDBC定義了五種事務隔離級別:
TRANSACTION_NONE JDBC驅動不支持事務
TRANSACTION_READ_UNCOMMITTED 允許髒讀、不可重複讀和幻讀。
TRANSACTION_READ_COMMITTED 禁止髒讀,但允許不可重複讀和幻讀。
TRANSACTION_REPEATABLE_READ 禁止髒讀和不可重複讀,單運行幻讀。
TRANSACTION_SERIALIZABLE 禁止髒讀、不可重複讀和幻讀。

3.保存點(SavePoint)
JDBC定義了SavePoint接口,提供在一個更細粒度的事務控制機制。當設置了一個保存點後,可以rollback到該保存點處的狀態,而不是rollback整個事務。
Connection接口的setSavepoint和releaseSavepoint方法可以設置和釋放保存點。

JDBC規範雖然定義了事務的以上支持行爲,但是各個JDBC驅動,數據庫廠商對事務的支持程度可能各不相同。如果在程序中任意設置,可能得不到想要的效果。爲此,JDBC提供了DatabaseMetaData接口,提供了一系列JDBC特性支持情況的獲取方法。比如,通過DatabaseMetaData.supportsTransactionIsolationLevel方法可以判斷對事務隔離級別的支持情況,通過DatabaseMetaData.supportsSavepoints方法可以判斷對保存點的支持情況。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章