當前位置:才華齋>計算機>java語言>

Java中的JDBC事務解析

java語言 閱讀(2.93W)

事務

Java中的JDBC事務解析

事務是一步或多步組成操作序列組成的邏輯執行單元,這個序列要麼全部執行,要麼則全部放棄執行。事務的四個特性:原子性(Atomicity)、一致性(Consistency)、隔離性(IsoIation)和持續性(Durability)原子性(Atomicity):事務應用最小的執行單元,不可再分。是事務中不可再分的最小邏輯執行體。

一致性(Consistency):事務的執行結果,必須使資料庫的從一個一致性的狀態變到另一個一致性的狀態。

隔離線(IsoIation):各個事務的執行互不干擾,任意一個事務的內部操作對其他併發的事務,都是隔離的。也就是:併發執行的事務之間不能看到對方的中間狀態,併發執行的事務之間不能互相影響。

持續性(Durability):持續性也稱為永續性(Persistence),指事務一旦提交,對資料所做的任何改變,都要記錄到永久儲存器中,通常就是儲存在物理資料庫中。

通常資料庫的事務涉及到的語句有:一組DML(Data Munipulation Language,資料操作語言)語句,這組DML語句修改後資料將保持較好的一致性; 操作表的語句,如插入、修改、刪除等;一個DDL(Data Definition Language,資料定義語言)語句,操作資料物件的語言,有create、alter、drop。一個DCL(Data Control Language,資料控制語言)語句,主要有grant、revoke語句。 DDL和DCL語句最多隻能有一個,因為它們都會導致事務的立即提交。當事務所包含的全部資料庫操作都成功執行後,應該提交事務,使這些修改永久生效。事務提交有兩種方式:顯示提交和自動提交。顯示提交:使用commit提交自動提交:執行DLL或DCL,或者程式正常退出 當事務包含的任意一個數據庫操作執行失敗後,應該回滾(rollback)事務,使該事務中所作的修改全部失效。事務的回滾方式有兩種:顯示回滾和自動回滾。顯示回滾:使用rollback自動回滾:系統錯誤或強行退出。

事務併發處理可能的問題

1、髒讀(dirty read):一個事務讀取了另一個事務尚未提交的資料

2、不可重複讀(non-repeatable read):一個事務的操作導致另一個事務前後兩次讀到不同的資料

3、幻讀(phantom read):一個事務的.操作導致另一個事務前後兩次查詢的結果資料量不同

舉例:

事務A、B併發執行時:

當A事務update後,B事務select讀取到A尚未提交的資料,此時A事務rollback,則B讀到的資料是無效的髒資料 當B事務select讀取資料後,A事務update操作更改B事務select到的資料,此時B事務再次讀取該資料,發現前後兩次的資料不一樣 當B事務select讀取資料後,A事務或了一條滿足A事務的select條件的記錄,此時B事務再次select,發現查詢到前次不存在的記錄,或者前次的某個記錄不見了

Java JDBC事務機制

import ection; import erManager; import aredStatement; import xception; public class JDBCTransaction { public static final String URL = "er"; public static final String USER = "root"; public static final String PASSWD = "123456"; public static void jdbcTransaction(int id) { Connection conn = null; PreparedStatement pstmt= null; PreparedStatement pstmtquery = null; String updatesql = "更新sql"; String querysql = "查詢sql"; try { ame("er"); conn = onnection(URL, USER, PASSWD); utoCommit(false); // 自動提交設定為false // 執行更新操作 pstmt= areStatement(updatesql); uteUpdate(); // 執行查詢操作 pstmtquery = areStatement(querysql); uteQuery(); it(); utoCommit(true); e(); e(); e(); } catch (Exception e) { try { back(); } catch (SQLException e1) {} tStackTrace(); } finally { try { if (pstmt!= null) { e(); } if (pstmtquery != null) { e(); } if (conn != null) { e(); } } catch (SQLException e2) {} } } }

JDBC的事務支援

JDBC的Connection也支援事物,Connection預設開啟自動提交,即關閉事物。也就是說,每條SQL語句執行就會立即提交到資料庫,永久生效,無法對其進行操作。關閉Connection的自動提交,開啟事物。Connection的setAutoCommit方法即可:utoCommit(false);通過utoCommit()來獲取事物的模式。當我們開啟事物後,在當前Connection中完成的資料庫操作,都不會立即提交到資料庫,需要呼叫Connection的commit方法才行。如果有語句執行失敗,可以呼叫rollback來回滾。注意:如果Connection遇到未處理的SQLException異常時,系統將非正常退出,系統會自動回滾該事務。如果程式捕捉了該異常,則需要在異常處理中顯示回滾事務。 Connection提供了設定事務中間儲存點的方法:setSavepoint,有2個方法可以設定中間點:Savepoint setSavepoint():在當前事務中建立一個未命名的中間點,並返回該中間點的Savepoint物件。Savepoint setSavepoint(String name):當前事務中建立一個具有指定名稱的中間點,並返回該中間點的Savepoint物件通常setSavepoint(String name)設定中間點的名稱,事務回滾並不是通過中間點的名稱進行回滾的,而是根據中間點物件進行回滾的。設定名稱只是更好的區分中間點物件,用Connection的rollback(Savepoint savepoint)方法即可完成回滾到指定中間點。

JDBC對事務的支援體現在三個方面:

1、自動提交模式(auto-commit mode)

Connection提供了一個auto-commit屬性來指定事務何時結束

2、當auto-commit為true時,當每個獨立SQL操作的執行完畢,事務立即自動提交,也就是說每個SQL操作都是一個事務

一個獨立SQL操作什麼時候算執行完畢,JDBC規範是這樣定義的:

對資料操作語言(DML)和資料定義語言(DDL),語句一執行完就視為執行完畢

3、當auto-commit為false時,每個事務都必須顯示呼叫commit方法進行提交,或者顯示呼叫rollback方法進行回滾。auto-commit預設為true

事務隔離級別(Transaction Isolation Levels)

JDBC定義了五種事務隔離級別:

TRANSACTION_NONE JDBC驅動不支援事務 TRANSACTION_READ_UNCOMMITTED 允許髒讀、不可重複讀和幻讀 TRANSACTION_READ_COMMITTED 禁止髒讀,但允許不可重複讀和幻讀 TRANSACTION_REPEATABLE_READ 禁止髒讀和不可重複讀,單執行幻讀 TRANSACTION_SERIALIZABLE 禁止髒讀、不可重複讀和幻讀儲存點。

JDBC定義了SavePoint介面,提供一個更細粒度的事務控制機制。當設定了一個儲存點後,可以rollback到該儲存點處的狀態,而不是rollback整個事務

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