如果你用Spring框架,Spring中可以實現(xiàn)事務(wù)管理,在spring 配置文件中配置事務(wù)管理器,也可以使用Spring注解式事務(wù),在方法上加上@Transactional注解。
創(chuàng)新互聯(lián)是一家專注于成都網(wǎng)站設(shè)計、網(wǎng)站制作與策劃設(shè)計,汕尾網(wǎng)站建設(shè)哪家好?創(chuàng)新互聯(lián)做網(wǎng)站,專注于網(wǎng)站建設(shè)10年,網(wǎng)設(shè)計領(lǐng)域的專業(yè)建站公司;建站業(yè)務(wù)涵蓋:汕尾等地區(qū)。汕尾做網(wǎng)站價格咨詢:13518219792
@Transactional
public void save() {
//你的代碼邏輯
}
如果沒有使用Spring框架,可以用JDBC處理事務(wù),如下:
try{
con.setAutoCommit(false);//開啟事務(wù) ......
con.commit();//try的最后提交事務(wù)
} catch() {
con.rollback();//回滾事務(wù)
}
看你是什么事務(wù),jdbc事務(wù),還是分布式事務(wù),還是容器事務(wù)
1,編程式事務(wù)管理(jdbc的事務(wù)是綁定在connection上的)
Connection conn = null;
try
{
Class.forName("com.mysql.jdbc.Driver");
conn = DriverManager.getConnection("jdbc:oracle:thin:@host:1521:SID","username","password");
conn.setAutoCommit(false); //取消自動提交
PreparedStatement ps = conn.prepareCall("update something");
ResultSet rs = ps.executeQuery();
conn.commit(); //手動提交
}
catch (Exception e)
{
conn.rollback();
e.printStackTrace();
}
finally
{
conn.close();
}
2,聲明式事務(wù)
先在工程的application.xml配置文件中添加如下代碼,開啟事務(wù)
!-- 聲明式事務(wù)控制配置 --
tx:annotation-driven transaction-manager="txManager"/
bean id="txManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"
property name="datasource" ref="bassDataSource"/property
/bean
然后在你需要開啟事務(wù)的接口前面添加注解
@Transactional(rollbackFor = IOException.class)
public void add(String name) throws IOException
{
System.out.println("可以再類里和方法里面添加事務(wù)注解0~0");
throw new IOException();
}
直接調(diào)用接口方法就好
分布式事務(wù)處理(mysql貌似在5.X之后才支持) 的話,
1.可以直接使用spring+atomikos框架進行管理
參考:
就不貼測試代碼了,自己看著配置吧
2,使用JTA(Java Transaction API)進行分布式事務(wù)管理(測試代碼如下)
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import javax.naming.InitialContext;
import javax.sql.DataSource;
import javax.transaction.SystemException;
import javax.transaction.UserTransaction;
import com.mysql.jdbc.jdbc2.optional.MysqlDataSource;
//分布式事務(wù)處理
public class transferAccount
{
@SuppressWarnings("null")
public void testTransferAccount()
{
UserTransaction userts = null;
Connection connA = null;
PreparedStatement psA = null;
InitialContext context = null;
Connection connB = null;
PreparedStatement psB = null;
try
{
//獲得事務(wù)管理對象
userts = (UserTransaction) context.lookup("java:comp/UserTransaction");
//獲取兩個數(shù)據(jù)庫
connA = getDataSourceA().getConnection();
connB = getDataSourceB().getConnection();
//開啟事務(wù)
userts.begin();
//sql語句
psA = connA.prepareStatement("我加1");
psB = connB.prepareStatement("我減1");
//執(zhí)行sql
psA.executeUpdate();
psB.executeUpdate();
//事務(wù)提交
userts.commit();
} catch (Exception e)
{
try
{
userts.rollback();
} catch (IllegalStateException | SecurityException
| SystemException e1)
{
e1.printStackTrace();
}
e.printStackTrace();
}
finally
{
try
{
psA.close();
psB.close();
connA.close();
connB.close();
} catch (SQLException e)
{
e.printStackTrace();
}
}
}
public DataSource getDataSourceA()
{
MysqlDataSource dataSource = new MysqlDataSource();
dataSource.setDatabaseName("mysql");
dataSource.setServerName("server");
dataSource.setPortNumber(1433);
dataSource.setUser("test");
dataSource.setPassword("test");
return dataSource;
}
public DataSource getDataSourceB()
{
MysqlDataSource dataSource = new MysqlDataSource();
dataSource.setDatabaseName("mysql");
dataSource.setServerName("server");
dataSource.setPortNumber(1435);
dataSource.setUser("test1");
dataSource.setPassword("test1");
return dataSource;
}
}
如果對數(shù)據(jù)庫進行多次操作,每一次的執(zhí)行或步驟都是一個事務(wù).如果數(shù)據(jù)庫操作在某一步?jīng)]有執(zhí)行或出現(xiàn)異常而導(dǎo)致事務(wù)失敗,這樣有的事務(wù)被執(zhí)行有的就沒有被執(zhí)行,從而就有了事務(wù)的回滾,取消先前的操作.....
JavaBean中使用JDBC方式進行事務(wù)處理
public int delete(int sID) {
dbc = new DataBaseConnection();
Connection con = dbc.getConnection();
try {
con.setAutoCommit(false);// 更改JDBC事務(wù)的默認提交方式
dbc.executeUpdate("delete from xiao where ID=" + sID);
dbc.executeUpdate("delete from xiao_content where ID=" + sID);
dbc.executeUpdate("delete from xiao_affix where bylawid=" + sID);
con.commit();//提交JDBC事務(wù)
con.setAutoCommit(true);// 恢復(fù)JDBC事務(wù)的默認提交方式
dbc.close();
return 1;
}
catch (Exception exc) {
con.rollBack();//回滾JDBC事務(wù)
exc.printStackTrace();
dbc.close();
return -1;
}
}
在數(shù)據(jù)庫操作中,一項事務(wù)是指由一條或多條對數(shù)據(jù)庫更新的sql語句所組成的一個不可分割的工作單元。只有當事務(wù)中的所有操作都正常完成了,整個事務(wù)才能被提交到數(shù)據(jù)庫,如果有一項操作沒有完成,就必須撤消整個事務(wù)。
例如在銀行的轉(zhuǎn)帳事務(wù)中,假定張三從自己的帳號上把1000元轉(zhuǎn)到李四的帳號上,相關(guān)的sql語句如下:
update account set monery=monery-1000 where name='zhangsan'
update account set monery=monery+1000 where name='lisi'
這個兩條語句必須作為一個完成的事務(wù)來處理。只有當兩條都成功執(zhí)行了,才能提交這個事務(wù)。如果有一句失敗,整個事務(wù)必須撤消。
在connection類中提供了3個控制事務(wù)的方法:
(1) setAutoCommit(Boolean autoCommit):設(shè)置是否自動提交事務(wù);
(2) commit();提交事務(wù);
(3) rollback();撤消事務(wù);
在jdbc api中,默認的情況為自動提交事務(wù),也就是說,每一條對數(shù)據(jù)庫的更新的sql語句代表一項事務(wù),操作成功后,系統(tǒng)自動調(diào)用commit()來提交,否則將調(diào)用rollback()來撤消事務(wù)。
在jdbc api中,可以通過調(diào)用setAutoCommit(false) 來禁止自動提交事務(wù)。然后就可以把多條更新數(shù)據(jù)庫的sql語句做為一個事務(wù),在所有操作完成之后,調(diào)用commit()來進行整體提交。倘若其中一項sql操作失敗,就不會執(zhí)行commit()方法,而是產(chǎn)生相應(yīng)的sqlexception,此時就可以捕獲異常代碼塊中調(diào)用rollback()方法撤消事務(wù)。
Java中的事務(wù)處理
一般情況下,J2EE應(yīng)用服務(wù)器支持JDBC事務(wù)、JTA(Java Transaction API)事務(wù)、容器管理事務(wù)。一般情況下,最好不要在程序中同時使用上述三種事務(wù)類型,比如在JTA事務(wù)中嵌套JDBC事務(wù)。第二方面,事務(wù)要在盡可能短的時間內(nèi)完成,不要在不同方法中實現(xiàn)事務(wù)的使用。下面我們列舉兩種事務(wù)處理方式。
1、JavaBean中使用JDBC方式進行事務(wù)處理
在JDBC中怎樣將多個SQL語句組合成一個事務(wù)呢?在JDBC中,打開一個連接對象Connection時,缺省是auto-commit模式,每個SQL語句都被當作一個事務(wù),即每次執(zhí)行一個語句,都會自動的得到事務(wù)確認。為了能將多個SQL語句組合成一個事務(wù),要將auto-commit模式屏蔽掉。在auto-commit模式屏蔽掉之后,如果不調(diào)用commit()方法,SQL語句不會得到事務(wù)確認。在最近一次commit()方法調(diào)用之后的所有SQL會在方法commit()調(diào)用時得到確認。
public int delete(int sID) {
dbc = new DataBaseConnection();
Connection con = dbc.getConnection();
try {
con.setAutoCommit(false);// 更改JDBC事務(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);
con.commit();//提交JDBC事務(wù)
con.setAutoCommit(true);// 恢復(fù)JDBC事務(wù)的默認提交方式
dbc.close();
return 1;
}
catch (Exception exc) {
con.rollBack();//回滾JDBC事務(wù)
exc.printStackTrace();
dbc.close();
return -1;
}
}
2、SessionBean中的JTA事務(wù)
JTA 是事務(wù)服務(wù)的 J2EE 解決方案。本質(zhì)上,它是描述事務(wù)接口(比如 UserTransaction 接口,開發(fā)人員直接使用該接口或者通過 J2EE 容器使用該接口來確保業(yè)務(wù)邏輯能夠可靠地運行)的 J2EE 模型的一部分。JTA 具有的三個主要的接口分別是 UserTransaction 接口、TransactionManager 接口和 Transaction 接口。這些接口共享公共的事務(wù)操作,例如 commit() 和 rollback(), 但是也包含特殊的事務(wù)操作,例如 suspend(),resume() 和 enlist(),它們只出現(xiàn)在特定的接口上,以便在實現(xiàn)中允許一定程度的訪問控制。例如,UserTransaction 能夠執(zhí)行事務(wù)劃分和基本的事務(wù)操作,而 TransactionManager 能夠執(zhí)行上下文管理。
應(yīng)用程序可以調(diào)用UserTransaction.begin()方法開始一個事務(wù),該事務(wù)與應(yīng)用程序正在其中運行的當前線程相關(guān)聯(lián)。底層的事務(wù)管理器實際處理線程與事務(wù)之間的關(guān)聯(lián)。UserTransaction.commit()方法終止與當前線程關(guān)聯(lián)的事務(wù)。UserTransaction.rollback()方法將放棄與當前線程關(guān)聯(lián)的當前事務(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;
}
}