如何用java開啟mysql事務,要求詳細
創(chuàng)新互聯(lián)建站專業(yè)為企業(yè)提供佛坪網(wǎng)站建設(shè)、佛坪做網(wǎng)站、佛坪網(wǎng)站設(shè)計、佛坪網(wǎng)站制作等企業(yè)網(wǎng)站建設(shè)、網(wǎng)頁設(shè)計與制作、佛坪企業(yè)網(wǎng)站模板建站服務,10年佛坪做網(wǎng)站經(jīng)驗,不只是建網(wǎng)站,更提供有價值的思路和整體網(wǎng)絡(luò)服務。
看你是什么事務,jdbc事務,還是分布式事務,還是容器事務
1,編程式事務管理(jdbc的事務是綁定在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,聲明式事務
先在工程的application.xml配置文件中添加如下代碼,開啟事務
!-- 聲明式事務控制配置 --
tx:annotation-driven transaction-manager="txManager"/
bean id="txManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"
property name="datasource" ref="bassDataSource"/property
/bean
然后在你需要開啟事務的接口前面添加注解
@Transactional(rollbackFor = IOException.class)
public void add(String name) throws IOException
{
System.out.println("可以再類里和方法里面添加事務注解0~0");
throw new IOException();
}
直接調(diào)用接口方法就好
分布式事務處理(mysql貌似在5.X之后才支持) 的話,
1.可以直接使用spring+atomikos框架進行管理
參考:
就不貼測試代碼了,自己看著配置吧
2,使用JTA(Java Transaction API)進行分布式事務管理(測試代碼如下)
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;
//分布式事務處理
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
{
//獲得事務管理對象
userts = (UserTransaction) context.lookup("java:comp/UserTransaction");
//獲取兩個數(shù)據(jù)庫
connA = getDataSourceA().getConnection();
connB = getDataSourceB().getConnection();
//開啟事務
userts.begin();
//sql語句
psA = connA.prepareStatement("我加1");
psB = connB.prepareStatement("我減1");
//執(zhí)行sql
psA.executeUpdate();
psB.executeUpdate();
//事務提交
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;
}
}
一、什么是Java事務 \x0d\x0a 通常的觀念認為,事務僅與數(shù)據(jù)庫相關(guān)。 \x0d\x0a 事務必須服從ISO/IEC所制定的ACID原則。ACID是原子性(atomicity)、一致性(consistency)、隔離性 \x0d\x0a(isolation)和持久性(durability)的縮寫。事務的原子性表示事務執(zhí)行過程中的任何失敗都將導致事務所做的任何修改失效。一致性表示\x0d\x0a \x0d\x0a當事務執(zhí)行失敗時,所有被該事務影響的數(shù)據(jù)都應該恢復到事務執(zhí)行前的狀態(tài)。隔離性表示在事務執(zhí)行過程中對數(shù)據(jù)的修改,在事務提交之前對其他事務不可見。持\x0d\x0a 久性表示已提交的數(shù)據(jù)在事務執(zhí)行失敗時,數(shù)據(jù)的狀態(tài)都應該正確。 \x0d\x0a 通俗的理解,事務是一組原子操作單元,從數(shù)據(jù)庫角度說,就是一組SQL指令,要么全部執(zhí)行成功,若因為某個原因其中一條指令執(zhí)行有錯誤,則撤銷先前執(zhí)行過的所有指令。更簡答的說就是:要么全部執(zhí)行成功,要么撤銷不執(zhí)行。 \x0d\x0a 既然事務的概念從數(shù)據(jù)庫而來,那Java事務是什么?之間有什么聯(lián)系? \x0d\x0a 實際上,一個Java應用系統(tǒng),如果要操作數(shù)據(jù)庫,則通過JDBC來實現(xiàn)的。增加、修改、刪除都是通過相應方法間接來實現(xiàn)的,事務的控制也相應轉(zhuǎn)移到Java程序代碼中。因此,數(shù)據(jù)庫操作的事務習慣上就稱為Java事務。 \x0d\x0a 二、為什么需要事務 \x0d\x0a 事務是為解決數(shù)據(jù)安全操作提出的,事務控制實際上就是控制數(shù)據(jù)的安全訪問。具一個簡單例子:比如銀行轉(zhuǎn)帳業(yè)務,賬戶A要將自己賬戶上的1000元 \x0d\x0a轉(zhuǎn)到B賬戶下面,A賬戶余額首先要減去1000元,然后B賬戶要增加1000元。假如在中間網(wǎng)絡(luò)出現(xiàn)了問題,A賬戶減去1000元已經(jīng)結(jié)束,B因為網(wǎng)絡(luò)中\(zhòng)x0d\x0a \x0d\x0a斷而操作失敗,那么整個業(yè)務失敗,必須做出控制,要求A賬戶轉(zhuǎn)帳業(yè)務撤銷。這才能保證業(yè)務的正確性,完成這個操走就需要事務,將A賬戶資金減少和B賬戶資\x0d\x0a 金增加方到一個事務里面,要么全部執(zhí)行成功,要么操作全部撤銷,這樣就保持了數(shù)據(jù)的安全性。 \x0d\x0a 三、Java事務的類型 \x0d\x0a Java事務的類型有三種:JDBC事務、JTA(Java Transaction API)事務、容器事務。 \x0d\x0a 1、JDBC事務 \x0d\x0a JDBC 事務是用 Connection 對象控制的。JDBC Connection 接口( java.sql.Connection )提供了兩種事務模式:自動提交和手工提交。 java.sql.Connection 提供了以下控制事務的方法: \x0d\x0a public void setAutoCommit(boolean) \x0d\x0a public boolean getAutoCommit() \x0d\x0a public void commit() \x0d\x0a public void rollback() \x0d\x0a 使用 JDBC 事務界定時,您可以將多個 SQL 語句結(jié)合到一個事務中。JDBC 事務的一個缺點是事務的范圍局限于一個數(shù)據(jù)庫連接。一個 JDBC 事務不能跨越多個數(shù)據(jù)庫。 \x0d\x0a 2、JTA(Java Transaction API)事務 \x0d\x0a JTA是一種高層的,與實現(xiàn)無關(guān)的,與協(xié)議無關(guān)的API,應用程序和應用服務器可以使用JTA來訪問事務。 \x0d\x0a JTA允許應用程序執(zhí)行分布式事務處理_在兩個或多個網(wǎng)絡(luò)計算機資源上訪問并且更新數(shù)據(jù),這些數(shù)據(jù)可以分布在多個數(shù)據(jù)庫上。JDBC驅(qū)動程序的JTA支持極大地增強了數(shù)據(jù)訪問能力。 \x0d\x0a 如果計劃用 JTA 界定事務,那么就需要有一個實現(xiàn) javax.sql.XADataSource 、 \x0d\x0ajavax.sql.XAConnection 和 javax.sql.XAResource 接口的 JDBC \x0d\x0a驅(qū)動程序。一個實現(xiàn)了這些接口的驅(qū)動程序?qū)⒖梢詤⑴c JTA 事務。一個 XADataSource 對象就是一個 XAConnection \x0d\x0a對象的工廠。 XAConnection s 是參與 JTA 事務的 JDBC 連接。 \x0d\x0a 您將需要用應用服務器的管理工具設(shè)置 XADataSource 。從應用服務器和 JDBC 驅(qū)動程序的文檔中可以了解到相關(guān)的指導。 \x0d\x0a J2EE 應用程序用 JNDI 查詢數(shù)據(jù)源。一旦應用程序找到了數(shù)據(jù)源對象,它就調(diào)用 javax.sql.DataSource.getConnection() 以獲得到數(shù)據(jù)庫的連接。 \x0d\x0a XA 連接與非 XA 連接不同。一定要記住 XA 連接參與了 JTA 事務。這意味著 XA 連接不支持 JDBC \x0d\x0a的自動提交功能。同時,應用程序一定不要對 XA 連接調(diào)用 java.sql.Connection.commit() 或者 \x0d\x0ajava.sql.Connection.rollback() 。相反,應用程序應該使用 UserTransaction.begin()、 \x0d\x0aUserTransaction.commit() 和 serTransaction.rollback() 。 \x0d\x0a 3、容器事務 \x0d\x0a 容器事務主要是J2EE應用服務器提供的,容器事務大多是基于JTA完成,這是一個基于JNDI的,相當復雜的API實現(xiàn)。相對編碼實現(xiàn)JTA事 \x0d\x0a務管理,我們可以通過EJB容器提供的容器事務管理機制(CMT)完成同一個功能,這項功能由J2EE應用服務器提供。這使得我們可以簡單的指定將哪個方\x0d\x0a 法加入事務,一旦指定,容器將負責事務管理任務。這是我們土建的解決方式,因為通過這種方式我們可以將事務代碼排除在邏輯編碼之外,同時將所有困難交給\x0d\x0a J2EE容器去解決。使用EJB CMT的另外一個好處就是程序員無需關(guān)心JTA API的編碼,不過,理論上我們必須使用EJB。 \x0d\x0a 四、三種事務差異 \x0d\x0a 1、JDBC事務控制的局限性在一個數(shù)據(jù)庫連接內(nèi),但是其使用簡單。 \x0d\x0a 2、JTA事務的功能強大,事務可以跨越多個數(shù)據(jù)庫或多個DAO,使用也比較復雜。 \x0d\x0a 3、容器事務,主要指的是J2EE應用服務器提供的事務管理,局限于EJB應用使用。 \x0d\x0a 五、總結(jié) \x0d\x0a 事務控制是構(gòu)建J2EE應用不可缺少的一部分,合理選擇應用何種事務對整個應用系統(tǒng)來說至關(guān)重要。一般說來,在單個JDBC \x0d\x0a連接連接的情況下可以選擇JDBC事務,在跨多個連接或者數(shù)據(jù)庫情況下,需要選擇使用JTA事務,如果用到了EJB,則可以考慮使用EJB容器事務。\x0d\x0a\x0d\x0a如果滿意請及時采納,謝謝~
如果對數(shù)據(jù)庫進行多次操作,每一次的執(zhí)行或步驟都是一個事務.如果數(shù)據(jù)庫操作在某一步?jīng)]有執(zhí)行或出現(xiàn)異常而導致事務失敗,這樣有的事務被執(zhí)行有的就沒有被執(zhí)行,從而就有了事務的回滾,取消先前的操作.....
JavaBean中使用JDBC方式進行事務處理
public int delete(int sID) {
dbc = new DataBaseConnection();
Connection con = dbc.getConnection();
try {
con.setAutoCommit(false);// 更改JDBC事務的默認提交方式
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事務
con.setAutoCommit(true);// 恢復JDBC事務的默認提交方式
dbc.close();
return 1;
}
catch (Exception exc) {
con.rollBack();//回滾JDBC事務
exc.printStackTrace();
dbc.close();
return -1;
}
}
在數(shù)據(jù)庫操作中,一項事務是指由一條或多條對數(shù)據(jù)庫更新的sql語句所組成的一個不可分割的工作單元。只有當事務中的所有操作都正常完成了,整個事務才能被提交到數(shù)據(jù)庫,如果有一項操作沒有完成,就必須撤消整個事務。
例如在銀行的轉(zhuǎn)帳事務中,假定張三從自己的帳號上把1000元轉(zhuǎn)到李四的帳號上,相關(guān)的sql語句如下:
update account set monery=monery-1000 where name='zhangsan'
update account set monery=monery+1000 where name='lisi'
這個兩條語句必須作為一個完成的事務來處理。只有當兩條都成功執(zhí)行了,才能提交這個事務。如果有一句失敗,整個事務必須撤消。
在connection類中提供了3個控制事務的方法:
(1) setAutoCommit(Boolean autoCommit):設(shè)置是否自動提交事務;
(2) commit();提交事務;
(3) rollback();撤消事務;
在jdbc api中,默認的情況為自動提交事務,也就是說,每一條對數(shù)據(jù)庫的更新的sql語句代表一項事務,操作成功后,系統(tǒng)自動調(diào)用commit()來提交,否則將調(diào)用rollback()來撤消事務。
在jdbc api中,可以通過調(diào)用setAutoCommit(false) 來禁止自動提交事務。然后就可以把多條更新數(shù)據(jù)庫的sql語句做為一個事務,在所有操作完成之后,調(diào)用commit()來進行整體提交。倘若其中一項sql操作失敗,就不會執(zhí)行commit()方法,而是產(chǎn)生相應的sqlexception,此時就可以捕獲異常代碼塊中調(diào)用rollback()方法撤消事務。
Java中的事務處理
一般情況下,J2EE應用服務器支持JDBC事務、JTA(JavaTransactionAPI)事務、容器管理事務。一般情況下,最好不要在程序中同時使用上述三種事務類型,比如在JTA事務中嵌套JDBC事務。第二方面,事務要在盡可能短的時間內(nèi)完成,不要在不同方法中實現(xiàn)事務的使用。下面我們列舉兩種事務處理方式。
1、JavaBean中使用JDBC方式進行事務處理
在JDBC中怎樣將多個SQL語句組合成一個事務呢?在JDBC中,打開一個連接對象Connection時,缺省是auto-commit模式,每個SQL語句都被當作一個事務,即每次執(zhí)行一個語句,都會自動的得到事務確認。為了能將多個SQL語句組合成一個事務,要將auto-commit模式屏蔽掉。在auto-commit模式屏蔽掉之后,如果不調(diào)用commit()方法,SQL語句不會得到事務確認。在最近一次commit()方法調(diào)用之后的所有SQL會在方法commit()調(diào)用時得到確認。
publicintdelete(intsID){
dbc=newDataBaseConnection();
Connectioncon=dbc.getConnection();
try{
con.setAutoCommit(false);//更改JDBC事務的默認提交方式
dbc.executeUpdate("deletefrombylawwhereID="+sID);
dbc.executeUpdate("deletefrombylaw_contentwhereID="+sID);
dbc.executeUpdate("deletefrombylaw_affixwherebylawid="+sID);
con.commit();//提交JDBC事務
con.setAutoCommit(true);//恢復JDBC事務的默認提交方式
dbc.close();
return1;
}
catch(Exceptionexc){
con.rollBack();//回滾JDBC事務
exc.printStackTrace();
dbc.close();
return-1;
}
}
2、SessionBean中的JTA事務
JTA是事務服務的J2EE解決方案。本質(zhì)上,它是描述事務接口(比如UserTransaction接口,開發(fā)人員直接使用該接口或者通過J2EE容器使用該接口來確保業(yè)務邏輯能夠可靠地運行)的J2EE模型的一部分。JTA具有的三個主要的接口分別是UserTransaction接口、TransactionManager接口和Transaction接口。這些接口共享公共的事務操作,例如commit()和rollback(),但是也包含特殊的事務操作,例如suspend(),resume()和enlist(),它們只出現(xiàn)在特定的接口上,以便在實現(xiàn)中允許一定程度的訪問控制。例如,UserTransaction能夠執(zhí)行事務劃分和基本的事務操作,而TransactionManager能夠執(zhí)行上下文管理。
應用程序可以調(diào)用UserTransaction.begin()方法開始一個事務,該事務與應用程序正在其中運行的當前線程相關(guān)聯(lián)。底層的事務管理器實際處理線程與事務之間的關(guān)聯(lián)。UserTransaction.commit()方法終止與當前線程關(guān)聯(lián)的事務。UserTransaction.rollback()方法將放棄與當前線程關(guān)聯(lián)的當前事務。
publicintdelete(intsID){
DataBaseConnectiondbc=null;
dbc=newDataBaseConnection();
dbc.getConnection();
UserTransactiontransaction=sessionContext.getUserTransaction();//獲得JTA事務
try{
transaction.begin();//開始JTA事務
dbc.executeUpdate("deletefrombylawwhereID="+sID);
dbc.executeUpdate("deletefrombylaw_contentwhereID="+sID);
dbc.executeUpdate("deletefrombylaw_affixwherebylawid="+sID);
transaction.commit();//提交JTA事務
dbc.close();
return1;
}
catch(Exceptionexc){
try{
transaction.rollback();//JTA事務回滾
}
catch(Exceptionex){
//JTA事務回滾出錯處理
ex.printStackTrace();
}
exc.printStackTrace();
dbc.close();
return-1;
}
}
如果你用Spring框架,Spring中可以實現(xiàn)事務管理,在spring 配置文件中配置事務管理器,也可以使用Spring注解式事務,在方法上加上@Transactional注解。
@Transactional
public void save() {
//你的代碼邏輯
}
如果沒有使用Spring框架,可以用JDBC處理事務,如下:
try{
con.setAutoCommit(false);//開啟事務 ......
con.commit();//try的最后提交事務
} catch() {
con.rollback();//回滾事務
}