基本概念
事務(wù)指邏輯上的一組操作,組成這組操作的各個單元,要么全部成功,要么全部不成功。
事務(wù)類型
JDBC事務(wù)
JDBC事務(wù)是用 Connection 對象控制的。JDBC Connection 接口( java.sql.Connection )提供了兩種事務(wù)模式:自動提交
與手工提交
。java.sql.Connection 提供了以下控制事務(wù)的辦法:
public void setAutoCommit(boolean)
public boolean getAutoCommit()
public void commit()
public void rollback()
使用 JDBC 事務(wù)界定時,可以將多個 SQL 語句結(jié)合到一個事務(wù)中。JDBC 事務(wù)的一個缺點(diǎn)是事務(wù)的范圍局限于一個數(shù)據(jù)庫連接。一個 JDBC 事務(wù)無法跨越多個數(shù)據(jù)庫。
public int delete(int sID) {
dbc = new DataBaseConnection();
Connection con = dbc.getConnection();
try {
con.setAutoCommit(false);// 更改JDBC事務(wù)的默認(rèn)提交方式
dbc.executeUpdate("delete from bylaw where ID=" + sID);
dbc.executeUpdate("delete from bylaw _content where ID=" + sID);
dbc.executeUpdate("delete from bylaw _affix where bylawid=" + sID);
con.commit();//提交JDBC事務(wù)
con.setAutoCommit(true);// 恢復(fù)JDBC事務(wù)的默認(rèn)提交方式
dbc.close();
return 1;
}
catch (Exception exc) {
con.rollBack();//回滾JDBC事務(wù)
exc.printStackTrace();
dbc.close();
return -1;
}
}
JTA(Java Transaction API)事務(wù)
JTA是一種高層的,與編寫無關(guān)的,與協(xié)議無關(guān)的API,應(yīng)用程序與應(yīng)用服務(wù)器可以使用JTA來訪問事務(wù)。
JTA允許應(yīng)用程序執(zhí)行分布式事務(wù)處理--在兩個或多個網(wǎng)絡(luò)計(jì)算機(jī)資源上訪問并且更新數(shù)據(jù),這些數(shù)據(jù)可以分布在多個數(shù)據(jù)庫上。JDBC驅(qū)動程序的JTA支持極大地增強(qiáng)了數(shù)據(jù)訪問能力。
如果計(jì)劃用JTA界定事務(wù),那么就需要有一個編寫javax.sql.XADataSource
javax.sql.XAConnection
與javax.sql.XAResource
接口的 JDBC 驅(qū)動程序。一個編寫了這些接口的驅(qū)動程序?qū)⒖梢詤⑴cJTA事務(wù)。一個XADataSource
對象就是一個XAConnection
對象的工廠。XAConnection s
是參與 JTA 事務(wù)的 JDBC 連接。
您將需要用應(yīng)用服務(wù)器的管理工具設(shè)置 XADataSource
。從應(yīng)用服務(wù)器與 JDBC 驅(qū)動程序的文檔中可以了解到相關(guān)的指導(dǎo)。
J2EE 應(yīng)用程序用 JNDI 查詢數(shù)據(jù)源。一旦應(yīng)用程序找到了數(shù)據(jù)源對象,它就調(diào)用 javax.sql.DataSource.getConnection()
以獲得到數(shù)據(jù)庫的連接。
XA連接
與非XA連接
區(qū)別。一定要記住 XA 連接參與了 JTA 事務(wù)。這意味著 XA 連接不支持 JDBC 的自動提交功能。同時,應(yīng)用程序一定不要對 XA 連接調(diào)用java.sql.Connection.commit()
或者java.sql.Connection.rollback()
。相反,應(yīng)用程序應(yīng)該使用 UserTransaction.begin()
、UserTransaction.commit()
與serTransaction.rollback()
。
JTA 是事務(wù)服務(wù)的 J2EE 解決方案。本質(zhì)上,它是描述事務(wù)接口(比如UserTransaction接口,開發(fā)人員直接使用該接口或者通過J2EE容器使用該接口來確保業(yè)務(wù)邏輯能夠可靠地運(yùn)行)的 J2EE 模型的一部分。JTA具有的三個主要的接口分別是UserTransaction接口
、TransactionManager接口
與Transaction接口
。這些接口共享公共的事務(wù)操作,例如commit()
與rollback()
,但是也包含特殊的事務(wù)操作,例如suspend()
,resume()
與 enlist(),它們只出現(xiàn)在特定的接口上,以便在編寫中允許一定程度的訪問控制。例如,UserTransaction能夠執(zhí)行事務(wù)劃分與基本的事務(wù)操作,而TransactionManager能夠執(zhí)行上下文管理。
應(yīng)用程序可以調(diào)用UserTransaction.begin()辦法開始一個事務(wù),該事務(wù)與應(yīng)用程序正在其中運(yùn)行的當(dāng)前線程相關(guān)聯(lián)。底層的事務(wù)管理器實(shí)際處理線程與事務(wù)之間的關(guān)聯(lián)。UserTransaction.commit()辦法終止與當(dāng)前線程關(guān)聯(lián)的事務(wù)。UserTransaction.rollback()辦法將放棄與當(dāng)前線程關(guān)聯(lián)的當(dāng)前事務(wù)。
public int delete(int sID) {
DataBaseConnection dbc = null;
dbc = new DataBaseConnection();
dbc.getConnection();
UserTransaction transaction = sessionContext.getUserTransaction();//獲得JTA事務(wù)
try {
transaction.begin(); //開始JTA事務(wù)
dbc.executeUpdate("delete from bylaw where ID=" + sID);
dbc.executeUpdate("delete from bylaw _content where ID=" + sID);
dbc.executeUpdate("delete from bylaw _affix where bylawid=" + sID);
transaction.commit(); //提交JTA事務(wù)
dbc.close();
return 1;
}
catch (Exception exc) {
try {
transaction.rollback();//JTA事務(wù)回滾
}
catch (Exception ex) {
//JTA事務(wù)回滾出錯處理
ex.printStackTrace();
}
exc.printStackTrace();
dbc.close();
return -1;
}
}
容器事務(wù)
容器事務(wù)主要是J2EE應(yīng)用服務(wù)器提供的,容器事務(wù)大多是基于JTA完成,這是一個基于JNDI的,相當(dāng)復(fù)雜的API編寫。相對編碼編寫JTA事務(wù)管理,我們可以通過EJB容器提供的容器事務(wù)管理機(jī)制(CMT)完成同一個功能,這項(xiàng)功能由J2EE應(yīng)用服務(wù)器提供。這使得我們可以簡單的指定將哪個辦法加入事務(wù),一旦指定,容器將負(fù)責(zé)事務(wù)管理任務(wù)。這是我們土建的解決方式,因?yàn)橥ㄟ^這種方式我們可以將事務(wù)代碼排除在邏輯編碼之外,同時將所有困難交給J2EE容器去解決。使用EJB CMT的另外一個好處就是程序員無需關(guān)心JTA API的編碼,不過,理論上我們必須使用EJB。
三種事務(wù)差異
- JDBC事務(wù)控制的局限性在一個數(shù)據(jù)庫連接內(nèi),但是其使用簡單。
- JTA事務(wù)的功能強(qiáng)大,事務(wù)可以跨越多個數(shù)據(jù)庫或多個DAO,使用也比較復(fù)雜。
- 容器事務(wù),主要指的是J2EE應(yīng)用服務(wù)器提供的事務(wù)管理,局限于EJB應(yīng)用使用。