如果你用Spring框架,Spring中可以實(shí)現(xiàn)事務(wù)管理,在spring 配置文件中配置事務(wù)管理器,也可以使用Spring注解式事務(wù),在方法上加上@Transactional注解。
公司主營(yíng)業(yè)務(wù):網(wǎng)站設(shè)計(jì)制作、做網(wǎng)站、移動(dòng)網(wǎng)站開(kāi)發(fā)等業(yè)務(wù)。幫助企業(yè)客戶(hù)真正實(shí)現(xiàn)互聯(lián)網(wǎng)宣傳,提高企業(yè)的競(jìng)爭(zhēng)能力。成都創(chuàng)新互聯(lián)公司是一支青春激揚(yáng)、勤奮敬業(yè)、活力青春激揚(yáng)、勤奮敬業(yè)、活力澎湃、和諧高效的團(tuán)隊(duì)。公司秉承以“開(kāi)放、自由、嚴(yán)謹(jǐn)、自律”為核心的企業(yè)文化,感謝他們對(duì)我們的高要求,感謝他們從不同領(lǐng)域給我們帶來(lái)的挑戰(zhàn),讓我們激情的團(tuán)隊(duì)有機(jī)會(huì)用頭腦與智慧不斷的給客戶(hù)帶來(lái)驚喜。成都創(chuàng)新互聯(lián)公司推出東遼免費(fèi)做網(wǎng)站回饋大家。
@Transactional
public void save() {
//你的代碼邏輯
}
如果沒(méi)有使用Spring框架,可以用JDBC處理事務(wù),如下:
try{
con.setAutoCommit(false);//開(kāi)啟事務(wù) ......
con.commit();//try的最后提交事務(wù)
} catch() {
con.rollback();//回滾事務(wù)
}
Java中為了控制事務(wù)的一致性,會(huì)使用插入回滾點(diǎn)、callback方法,保證數(shù)據(jù)不被篡改,示例如下:
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事務(wù)
con.setAutoCommit(true);
db.close();
return “success”;
}
catch (Exception e) {
con.rollBack();//回滾JDBC事務(wù)
e.printStackTrace();
db.close();
return “fail”;
}
}
看你是什么事務(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); //取消自動(dòng)提交
PreparedStatement ps = conn.prepareCall("update something");
ResultSet rs = ps.executeQuery();
conn.commit(); //手動(dòng)提交
}
catch (Exception e)
{
conn.rollback();
e.printStackTrace();
}
finally
{
conn.close();
}
2,聲明式事務(wù)
先在工程的application.xml配置文件中添加如下代碼,開(kāi)啟事務(wù)
!-- 聲明式事務(wù)控制配置 --
tx:annotation-driven transaction-manager="txManager"/
bean id="txManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"
property name="datasource" ref="bassDataSource"/property
/bean
然后在你需要開(kāi)啟事務(wù)的接口前面添加注解
@Transactional(rollbackFor = IOException.class)
public void add(String name) throws IOException
{
System.out.println("可以再類(lèi)里和方法里面添加事務(wù)注解0~0");
throw new IOException();
}
直接調(diào)用接口方法就好
分布式事務(wù)處理(mysql貌似在5.X之后才支持) 的話(huà),
1.可以直接使用spring+atomikos框架進(jìn)行管理
參考:
就不貼測(cè)試代碼了,自己看著配置吧
2,使用JTA(Java Transaction API)進(jìn)行分布式事務(wù)管理(測(cè)試代碼如下)
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()
{
把錯(cuò)誤原因貼出來(lái)吧。而且你的這段代碼本身存在編譯的問(wèn)題,變量conn是在try{}中定義的,在catch(){}塊中根本就沒(méi)有這個(gè)變量,編譯能通過(guò)嗎?
如果對(duì)數(shù)據(jù)庫(kù)進(jìn)行多次操作,每一次的執(zhí)行或步驟都是一個(gè)事務(wù).如果數(shù)據(jù)庫(kù)操作在某一步?jīng)]有執(zhí)行或出現(xiàn)異常而導(dǎo)致事務(wù)失敗,這樣有的事務(wù)被執(zhí)行有的就沒(méi)有被執(zhí)行,從而就有了事務(wù)的回滾,取消先前的操作.....
JavaBean中使用JDBC方式進(jìn)行事務(wù)處理
public int delete(int sID) {
dbc = new DataBaseConnection();
Connection con = dbc.getConnection();
try {
con.setAutoCommit(false);// 更改JDBC事務(wù)的默認(rèn)提交方式
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ù)的默認(rèn)提交方式
dbc.close();
return 1;
}
catch (Exception exc) {
con.rollBack();//回滾JDBC事務(wù)
exc.printStackTrace();
dbc.close();
return -1;
}
}
在數(shù)據(jù)庫(kù)操作中,一項(xiàng)事務(wù)是指由一條或多條對(duì)數(shù)據(jù)庫(kù)更新的sql語(yǔ)句所組成的一個(gè)不可分割的工作單元。只有當(dāng)事務(wù)中的所有操作都正常完成了,整個(gè)事務(wù)才能被提交到數(shù)據(jù)庫(kù),如果有一項(xiàng)操作沒(méi)有完成,就必須撤消整個(gè)事務(wù)。
例如在銀行的轉(zhuǎn)帳事務(wù)中,假定張三從自己的帳號(hào)上把1000元轉(zhuǎn)到李四的帳號(hào)上,相關(guān)的sql語(yǔ)句如下:
update account set monery=monery-1000 where name='zhangsan'
update account set monery=monery+1000 where name='lisi'
這個(gè)兩條語(yǔ)句必須作為一個(gè)完成的事務(wù)來(lái)處理。只有當(dāng)兩條都成功執(zhí)行了,才能提交這個(gè)事務(wù)。如果有一句失敗,整個(gè)事務(wù)必須撤消。
在connection類(lèi)中提供了3個(gè)控制事務(wù)的方法:
(1) setAutoCommit(Boolean autoCommit):設(shè)置是否自動(dòng)提交事務(wù);
(2) commit();提交事務(wù);
(3) rollback();撤消事務(wù);
在jdbc api中,默認(rèn)的情況為自動(dòng)提交事務(wù),也就是說(shuō),每一條對(duì)數(shù)據(jù)庫(kù)的更新的sql語(yǔ)句代表一項(xiàng)事務(wù),操作成功后,系統(tǒng)自動(dòng)調(diào)用commit()來(lái)提交,否則將調(diào)用rollback()來(lái)撤消事務(wù)。
在jdbc api中,可以通過(guò)調(diào)用setAutoCommit(false) 來(lái)禁止自動(dòng)提交事務(wù)。然后就可以把多條更新數(shù)據(jù)庫(kù)的sql語(yǔ)句做為一個(gè)事務(wù),在所有操作完成之后,調(diào)用commit()來(lái)進(jìn)行整體提交。倘若其中一項(xiàng)sql操作失敗,就不會(huì)執(zhí)行commit()方法,而是產(chǎn)生相應(yīng)的sqlexception,此時(shí)就可以捕獲異常代碼塊中調(diào)用rollback()方法撤消事務(wù)。
一、什么是Java事務(wù)
通常的觀(guān)念認(rèn)為,事務(wù)僅與數(shù)據(jù)庫(kù)相關(guān)。
事務(wù)必須服從ISO/IEC所制定的ACID原則。ACID是原子性(atomicity)、一致性(consistency)、隔離性
(isolation)和持久性(durability)的縮寫(xiě)。事務(wù)的原子性表示事務(wù)執(zhí)行過(guò)程中的任何失敗都將導(dǎo)致事務(wù)所做的任何修改失效。一致性表示
當(dāng)事務(wù)執(zhí)行失敗時(shí),所有被該事務(wù)影響的數(shù)據(jù)都應(yīng)該恢復(fù)到事務(wù)執(zhí)行前的狀態(tài)。隔離性表示在事務(wù)執(zhí)行過(guò)程中對(duì)數(shù)據(jù)的修改,在事務(wù)提交之前對(duì)其他事務(wù)不可見(jiàn)。持
久性表示已提交的數(shù)據(jù)在事務(wù)執(zhí)行失敗時(shí),數(shù)據(jù)的狀態(tài)都應(yīng)該正確。
通俗的理解,事務(wù)是一組原子操作單元,從數(shù)據(jù)庫(kù)角度說(shuō),就是一組SQL指令,要么全部執(zhí)行成功,若因?yàn)槟硞€(gè)原因其中一條指令執(zhí)行有錯(cuò)誤,則撤銷(xiāo)先前執(zhí)行過(guò)的所有指令。更簡(jiǎn)答的說(shuō)就是:要么全部執(zhí)行成功,要么撤銷(xiāo)不執(zhí)行。
既然事務(wù)的概念從數(shù)據(jù)庫(kù)而來(lái),那Java事務(wù)是什么看之間有什么聯(lián)系看
實(shí)際上,一個(gè)Java應(yīng)用系統(tǒng),如果要操作數(shù)據(jù)庫(kù),則通過(guò)JDBC來(lái)實(shí)現(xiàn)的。增加、修改、刪除都是通過(guò)相應(yīng)方法間接來(lái)實(shí)現(xiàn)的,事務(wù)的控制也相應(yīng)轉(zhuǎn)移到Java程序代碼中。因此,數(shù)據(jù)庫(kù)操作的事務(wù)習(xí)慣上就稱(chēng)為Java事務(wù)。
二、為什么需要事務(wù)
事務(wù)是為解決數(shù)據(jù)安全操作提出的,事務(wù)控制實(shí)際上就是控制數(shù)據(jù)的安全訪(fǎng)問(wèn)。具一個(gè)簡(jiǎn)單例子:比如銀行轉(zhuǎn)帳業(yè)務(wù),賬戶(hù)A要將自己賬戶(hù)上的1000元
轉(zhuǎn)到B賬戶(hù)下面,A賬戶(hù)余額首先要減去1000元,然后B賬戶(hù)要增加1000元。假如在中間網(wǎng)絡(luò)出現(xiàn)了問(wèn)題,A賬戶(hù)減去1000元已經(jīng)結(jié)束,B因?yàn)榫W(wǎng)絡(luò)中
斷而操作失敗,那么整個(gè)業(yè)務(wù)失敗,必須做出控制,要求A賬戶(hù)轉(zhuǎn)帳業(yè)務(wù)撤銷(xiāo)。這才能保證業(yè)務(wù)的正確性,完成這個(gè)操走就需要事務(wù),將A賬戶(hù)資金減少和B賬戶(hù)資
金增加方到一個(gè)事務(wù)里面,要么全部執(zhí)行成功,要么操作全部撤銷(xiāo),這樣就保持了數(shù)據(jù)的安全性。
三、Java事務(wù)的類(lèi)型
Java事務(wù)的類(lèi)型有三種:JDBC事務(wù)、JTA(Java Transaction API)事務(wù)、容器事務(wù)。
1、JDBC事務(wù)
JDBC 事務(wù)是用 Connection 對(duì)象控制的。JDBC Connection 接口( java.sql.Connection )提供了兩種事務(wù)模式:自動(dòng)提交和手工提交。 java.sql.Connection 提供了以下控制事務(wù)的方法:
public void setAutoCommit(boolean)
public boolean getAutoCommit()
public void commit()
public void rollback()
使用 JDBC 事務(wù)界定時(shí),您可以將多個(gè) SQL 語(yǔ)句結(jié)合到一個(gè)事務(wù)中。JDBC 事務(wù)的一個(gè)缺點(diǎn)是事務(wù)的范圍局限于一個(gè)數(shù)據(jù)庫(kù)連接。一個(gè) JDBC 事務(wù)不能跨越多個(gè)數(shù)據(jù)庫(kù)。
2、JTA(Java Transaction API)事務(wù)
JTA是一種高層的,與實(shí)現(xiàn)無(wú)關(guān)的,與協(xié)議無(wú)關(guān)的API,應(yīng)用程序和應(yīng)用服務(wù)器可以使用JTA來(lái)訪(fǎng)問(wèn)事務(wù)。
JTA允許應(yīng)用程序執(zhí)行分布式事務(wù)處理–在兩個(gè)或多個(gè)網(wǎng)絡(luò)計(jì)算機(jī)資源上訪(fǎng)問(wèn)并且更新數(shù)據(jù),這些數(shù)據(jù)可以分布在多個(gè)數(shù)據(jù)庫(kù)上。JDBC驅(qū)動(dòng)程序的JTA支持極大地增強(qiáng)了數(shù)據(jù)訪(fǎng)問(wèn)能力。
如果計(jì)劃用 JTA 界定事務(wù),那么就需要有一個(gè)實(shí)現(xiàn) javax.sql.XADataSource 、
javax.sql.XAConnection 和 javax.sql.XAResource 接口的 JDBC
驅(qū)動(dòng)程序。一個(gè)實(shí)現(xiàn)了這些接口的驅(qū)動(dòng)程序?qū)⒖梢詤⑴c JTA 事務(wù)。一個(gè) XADataSource 對(duì)象就是一個(gè) XAConnection
對(duì)象的工廠(chǎng)。 XAConnection s 是參與 JTA 事務(wù)的 JDBC 連接。
您將需要用應(yīng)用服務(wù)器的管理工具設(shè)置 XADataSource 。從應(yīng)用服務(wù)器和 JDBC 驅(qū)動(dòng)程序的文檔中可以了解到相關(guān)的指導(dǎo)。
J2EE 應(yīng)用程序用 JNDI 查詢(xún)數(shù)據(jù)源。一旦應(yīng)用程序找到了數(shù)據(jù)源對(duì)象,它就調(diào)用 javax.sql.DataSource.getConnection() 以獲得到數(shù)據(jù)庫(kù)的連接。
XA 連接與非 XA 連接不同。一定要記住 XA 連接參與了 JTA 事務(wù)。這意味著 XA 連接不支持 JDBC
的自動(dòng)提交功能。同時(shí),應(yīng)用程序一定不要對(duì) XA 連接調(diào)用 java.sql.Connection.commit() 或者
java.sql.Connection.rollback() 。相反,應(yīng)用程序應(yīng)該使用 UserTransaction.begin()、
UserTransaction.commit() 和 serTransaction.rollback() 。
3、容器事務(wù)
容器事務(wù)主要是J2EE應(yīng)用服務(wù)器提供的,容器事務(wù)大多是基于JTA完成,這是一個(gè)基于JNDI的,相當(dāng)復(fù)雜的API實(shí)現(xiàn)。相對(duì)編碼實(shí)現(xiàn)JTA事
務(wù)管理,我們可以通過(guò)EJB容器提供的容器事務(wù)管理機(jī)制(CMT)完成同一個(gè)功能,這項(xiàng)功能由J2EE應(yīng)用服務(wù)器提供。這使得我們可以簡(jiǎn)單的指定將哪個(gè)方
法加入事務(wù),一旦指定,容器將負(fù)責(zé)事務(wù)管理任務(wù)。這是我們土建的解決方式,因?yàn)橥ㄟ^(guò)這種方式我們可以將事務(wù)代碼排除在邏輯編碼之外,同時(shí)將所有困難交給
J2EE容器去解決。使用EJB CMT的另外一個(gè)好處就是程序員無(wú)需關(guān)心JTA API的編碼,不過(guò),理論上我們必須使用EJB。
四、三種事務(wù)差異
1、JDBC事務(wù)控制的局限性在一個(gè)數(shù)據(jù)庫(kù)連接內(nèi),但是其使用簡(jiǎn)單。
2、JTA事務(wù)的功能強(qiáng)大,事務(wù)可以跨越多個(gè)數(shù)據(jù)庫(kù)或多個(gè)DAO,使用也比較復(fù)雜。
3、容器事務(wù),主要指的是J2EE應(yīng)用服務(wù)器提供的事務(wù)管理,局限于EJB應(yīng)用使用。
五、總結(jié)
事務(wù)控制是構(gòu)建J2EE應(yīng)用不可缺少的一部分,合理選擇應(yīng)用何種事務(wù)對(duì)整個(gè)應(yīng)用系統(tǒng)來(lái)說(shuō)至關(guān)重要。一般說(shuō)來(lái),在單個(gè)JDBC
連接連接的情況下可以選擇JDBC事務(wù),在跨多個(gè)連接或者數(shù)據(jù)庫(kù)情況下,需要選擇使用JTA事務(wù),如果用到了EJB,則可以考慮使用EJB容器事務(wù)。
如果滿(mǎn)意請(qǐng)及時(shí)~~,謝謝~