java事務管理
一、事務概念
事務,通俗講就是一組操作資料庫的動作集合。事務(Transaction):是併發控制的單元,是使用者定義的一個操作序列。這些操作要麼都做,要麼都不做,是一個不可分割的工作單位。通過事務,sql server 能將邏輯相關的一組操作繫結在一起,以便伺服器 保持資料的完整性。
事務是現代資料庫理論中的核心概念之一。如果一組處理步驟或者全部發生或者一步也不執行,我們稱該組處理步驟為一個事務。當所有的步驟像一個操作一樣被完整地執行,我們稱該事務被提交。由於其中的一部分或多步執行失敗,導致沒有步驟被提交,則事務必須回滾到最初的系統狀態。
事務必須服從ISO/IEC所制定的ACID原則。ACID是原子性(atomicity)、一致性(consistency)、隔離性(isolation)和永續性(durability)的縮寫。
二、為什麼需要事務
事務是為解決資料安全操作提出的,事務控制實際上就是控制資料的安全訪問。具一個簡單例子:比如銀行轉帳業務,賬戶A要將自己賬戶上的1000元轉到B賬戶下面,A賬戶餘額首先要減去1000元,然後B賬戶要增加1000元。假如在中間網路出現了問題,A賬戶減去1000元已經結束,B因為網路中斷而操作失敗,那麼整個業務失敗,必須做出控制,要求A賬戶轉帳業務撤銷。這才能保證業務的正確性,完成這個操走就需要事務,將A賬戶資金減少和B賬戶資金增加方到一個事務裡面,要麼全部執行成功,要麼操作全部撤銷,這樣就保持了資料的安全性。
三、Java中的事務處理
一般J2EE伺服器支援三種類型的事務管理。即:JDBC事務,JTA(Java Transaction API)事務,容器管理事務。
最好不要在程式中同時使用上述三種事務型別;並且,事務要在儘可能短的時間內完成,不要在不同方法中實現事務的使用。下面舉兩個例子說明JDBC及JTA事務,容器管理事務是在特定的框架中實現的(如:Spring的事務管理)
1. JDBC事務
JDBC 事務是用 Connection 物件控制的。JDBC Connection 介面( java.sql.Connection)提供了兩種事務模式:自動提交和手工提交。 java.sql.Connection 提供了以下控制事務的方法:
public void setAutoCommit(boolean)
public boolean getAutoCommit()
public void commit()
public void rollback()
使用 JDBC 事務界定時,您可以將多個 SQL 語句結合到一個事務中。JDBC 事務的一個缺點是事務的範圍侷限於一個數據庫連線。一個 JDBC 事務不能跨越多個數據庫。
自動提交事務:每條單獨的語句都是一個事務。每個語句後都隱含一個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語句之前,該事務將一直保持有效。在第一個事務被提交或回滾之後,下次當連線執行以上任何語句時,資料庫引擎例項都將自動啟動一個新事務。該例項將不斷地生成隱性事務鏈,直到隱性事務模式關閉為止。
JDBC舉例說明事務處理
public String delete(String id) {
String ID = id;
db = new getConnection();
Connection con = db.getConnection();
try {
con.setAutoCommit(false);
db.executeUpdate("delete from helloworld where ID=" + ID); //更新操作1
db.executeUpdate("delete from helloworld _book where ID=" + ID); //更新操作2
db.executeUpdate("delete from helloworld_user where ID=" + ID); //更新操作3
con.commit();//提交JDBC事務
con.setAutoCommit(true);
db.close();
return “success”;
}
catch (Exception e) {
con.rollBack();//回滾JDBC事務
e.printStackTrace();
db.close();
return “fail”;
}
}
如上例:更新操作1,2,3只有當三步操作都成功完成才進行提交,否則回滾已經進行的操作。這樣,保證了資料的完整性,不會因為突然斷電等特殊情況導致的資料錯誤。
2.JTA事務
JTA(Java Transaction API)是一種高層的,與實現無關的,與協議無關的API,應用程式和應用伺服器可以使用JTA來訪問事務。
JTA允許應用程式執行分散式事務處理–在兩個或多個網路計算機資源上訪問並且更新資料,這些資料可以分佈在多個數據庫上。JDBC驅動程式的JTA支援極大地增強了資料訪問能力。
JTA是J2EE事務服務的解決方案、描述了J2EE模型事務介面。JTA具有三個主要的介面:UserTransaction、TransactionManager、Transaction介面。這些介面共享公共的事務操作,如:commit()、rollback()。同時各自也有自己的操作。
舉例說明:
public String delete(String id) {
String ID = id;
db = new getConnection();
db.getConnection();
UserTransaction transaction = sessionContext.getUserTransaction();//獲得JTA事務
try {
transaction.begin(); //開始JTA事務
db.executeUpdate("delete from helloworld where ID=" + ID);
db.executeUpdate("delete from helloworld _book where ID=" + ID);
db.executeUpdate("delete from helloworld _user where ID=" + ID);
transaction.commit(); //提交JTA事務
db.close();
return”success”;
}
catch (Exception e) {
try {
transaction.rollback();//事務回滾
}
catch (Exception e) {
e.printStackTrace();
}
exc.printStackTrace();
db.close();
return “fail”;
}
}
3.容器事務管理
在Spring、Hibernate等框架中都有各自的事務管理功能。雖然表現形式有些差別,但都是在JAVA事務管理的基礎上實現的。將在下一節介紹。
四、三種事務差異
1、JDBC事務控制的侷限性在一個數據庫連線內,但是其使用簡單。
2、JTA事務的功能強大,事務可以跨越多個數據庫或多個DAO,使用也比較複雜。
3、容器事務,主要指的是J2EE應用伺服器提供的事務管理,侷限於EJB應用使用。
注:事務併發處理可能引起的問題
* 髒讀(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,發現查詢到前次不存在的記錄("幻影"),或者前次的某個記錄不見了。