Ⅰ java中jdbc多表操作如何事物回滾
可以把要執行的四個SQL語句寫到同一個List中再調用此方法
你也可以自己寫
主要注意
執行sql插入前要取消自動提交
con.setAutoCommit(false);
全部sql語句執行完成後再提交
con.commit();
執行過程拋出異常則回滾
con.rollback();
希望對你有幫助
public
boolean
exeupdate(List<String>
sqls)
throws
SQLException
{
boolean
flag
=
false;
openPoolConnection();//創建連接
try
{
//
con.setAutoCommit(false);//取消自動提交
for(int
i=0;i<sqls.size();i++)
{
pstmt
=
con.prepareStatement(sqls.get(i));
int
rows
=
pstmt.executeUpdate();
}
flag
=
true;
con.commit();//提交
}
catch
(Exception
e)
{
con.rollback();//回滾
e.printStackTrace();
}
finally
{
this.closeAll();//關閉連接
數據集
語句對象
}
return
flag;
}
Ⅱ jdbc事務回滾java操作
事務控制,一起提交或回滾。
Connection
conn
=
....
//
取得資料庫連接;
conn.setAutoCommit(false);
//
關閉自動提交;
try{
......
//
你的處理數據代碼回.
conn.commit();
//
提交事務.
}catch(Exception
ex){
conn.rollback();
//
失敗回滾答.
}
Ⅲ 在jdbc中回滾是什麼意思
回滾必須要配合上事務。
在事務中如果正常執行就執行提交commit.如果中間出現問題,可以使用rollback()來撤銷事務中所包含的所有操作。
所以一般都會把回滾放在catch中
Ⅳ 簡答題 應用JDBC技術對如何保證多條SQL命令要麼都成功,要麼都失敗。 求Java大神
如果JDBC連接處於自動提交模式,默認情況下,則每個SQL語句在完成後都會提交到資料庫。
對於簡單的應用程序可能沒有問題,但是有三個原因需要考慮是否關閉自動提交並管理自己的事務 -
提高性能
保持業務流程的完整性
使用分布式事務
事務能夠控制何時更改提交並應用於資料庫。 它將單個SQL語句或一組SQL語句視為一個邏輯單元,如果任何語句失敗,整個事務將失敗。
要啟用手動事務支持,而不是使用JDBC驅動程序默認使用的自動提交模式,請調用Connection對象的setAutoCommit()方法。 如果將布爾的false傳遞給setAutoCommit(),則關閉自動提交。 也可以傳遞一個布爾值true來重新打開它。
例如,如果有一個名為conn的Connection對象,請將以下代碼關閉自動提交 -
提交和回滾
完成更改後,若要提交更改,那麼可在連接對象上調用commit()方法,如下所示:
否則,要使用連接名為conn的資料庫回滾更新,請使用以下代碼 -
以下示例說明了如何使用提交和回滾對象 -
在這種情況下,上述INSERT語句不會成功執行,因為所有操作都被回滾了。
為了更好的理解,建議學習研究「事務提交示例代碼」。
使用保存點
新的JDBC 3.0新添加了Savepoint介面提供了額外的事務控制能力。大多數現代DBMS支持其環境中的保存點,如Oracle的PL/SQL。
設置保存點(Savepoint)時,可以在事務中定義邏輯回滾點。 如果通過保存點(Savepoint)發生錯誤時,則可以使用回滾方法來撤消所有更改或僅保存保存點之後所做的更改。
Connection對象有兩種新的方法可用來管理保存點 -
setSavepoint(String savepointName):- 定義新的保存點,它還返回一個Savepoint對象。
releaseSavepoint(Savepoint savepointName):- 刪除保存點。要注意,它需要一個Savepoint對象作為參數。 該對象通常是由setSavepoint()方法生成的保存點。
有一個rollback (String savepointName)方法,它將使用事務回滾到指定的保存點。
以下示例說明了使用Savepoint對象 -
在這種情況下,上述INSERT語句都不會成功,因為所有操作都被回滾了。
為了更好的理解,建議學習研究保存點示例代碼。
原文地址:網頁鏈接
Ⅳ jdbc如何實現資料庫跨庫事務刪除回滾的問題
1. Connection.setAutoCommit(boolean );//設置自動提交模式,false表示禁用自動提交模式;
2. 用Savepoint對象的setSavapoint(String name);
3 rollback()取消在當前事務中進行的所有更改;
4. rollback (Savepoint )//回退到保存點 狀態;
5. commit ()提交事務;
Ⅵ java中的JDBC事務和JTA的區別是什麼
在說他們之間的區別之前,先考慮如下幾個問題:
1、getCurrentSession()與openSession()的區別?
* 採用getCurrentSession()創建的session會綁定到當前線程中,而採用openSession()
創建的session則不會
* 採用getCurrentSession()創建的session在commit或rollback時會自動關閉,而採用openSession()
創建的session必須手動關閉
2、使用getCurrentSession()需要在hibernate.cfg.xml文件中加入如下配置:
* 如果使用的是本地事務(jdbc事務)
<property name="hibernate.current_session_context_class">thread</property>
* 如果使用的是全局事務(jta事務)
<property name="hibernate.current_session_context_class">jta</property>
以上是hibernate中一些使用,下面來說說jdbc與jta的區別:
JDBC 事務
JDBC 事務是用 Connection 對象控制的。JDBC Connection 介面( java.sql.Connection )提供了兩種事務模式:自動提交和手工提交。
#在jdbc中,事務操作預設是自動提交。也就是說,一條對資料庫的更新表達式代表一項事務操作,操作成功後,系統將自動調用commit()來提交,否則將調用rollback()來回滾。
# 在jdbc中,可以通過調用setAutoCommit(false)來禁止自動提交。之後就可以把多個資料庫操作的表達式作為一個事務,在操作完成後調 用commit()來進行整體提交,倘若其中一個表達式操作失敗,都不會執行到commit(),並且將產生響應的異常;此時就可以在異常捕獲時調用 rollback()進行回滾。這樣做可以保持多次更新操作後,相關數據的一致性,示例如下:
try {
conn =
DriverManager.getConnection
("jdbc:oracle:thin:@host:1521:SID","username","userpwd";
conn.setAutoCommit(false);//禁止自動提交,設置回滾點
stmt = conn.createStatement();
stmt.executeUpdate(「alter table …」); //資料庫更新操作1
stmt.executeUpdate(「insert into table …」); //資料庫更新操作2
conn.commit(); //事務提交
}catch(Exception ex) {
ex.printStackTrace();
try {
conn.rollback(); //操作不成功則回滾
}catch(Exception e) {
e.printStackTrace();
}
}
JDBC 事務的一個缺點是事務的范圍局限於一個資料庫連接。一個 JDBC 事務不能跨越多個資料庫。
JTA事務
JTA(Java Transaction API) 為 J2EE 平台提供了分布式事務服務。
要用 JTA 進行事務界定,應用程序要調用 javax.transaction.UserTransaction 介面中的方法。例如:
utx.begin();
// ...
DataSource ds = obtainXADataSource();
Connection conn = ds.getConnection();
pstmt = conn.prepareStatement("UPDATE MOVIES ...");
pstmt.setString(1, "Spinal Tap");
pstmt.executeUpdate();
// ...
utx.commit();
讓我們來關注下面的話:
「用 JTA 界定事務,那麼就需要有一個實現 javax.sql.XADataSource 、 javax.sql.XAConnection 和 javax.sql.XAResource 介面的 JDBC 驅動程序。一個實現了這些介面的驅動程序將可以參與 JTA 事務。一個 XADataSource 對象就是一個 XAConnection 對象的工廠。 XAConnection s 是參與 JTA 事務的 JDBC 連接。」
要使用JTA事務,必須使用XADataSource來產生資料庫連接,產生的連接為一個XA連接。
XA連接(javax.sql.XAConnection)和非XA(java.sql.Connection)連接的區別在於:XA可以參與JTA的事務,而且不支持自動提交。
注意:
Oracle, Sybase, DB2, SQL Server等大型資料庫才支持XA, 支持分布事務。
My SQL 連本地都支持不好,更別說分布事務了。
JTA方式的實現過程:
用XADataSource產生的XAConnection它擴展了一個getXAResource()方法,事務通過這個方法把它加入到事務容器中進行 管理.對於調用者來說,根本看不到事務是如果管理的,你只要聲明開始事務,告訴容器我下面的操作要求事務參與了,最後告訴事務說到這兒可以提交或回滾了, 別的都是黑箱操作。
在使用JTA之前,你必須首先實現一個Xid類用來標識事務(在普通情況下這將由事務管理程序來處理)。Xid包含三個元素:formatID、gtrid(全局事務標識符)和bqual(分支修飾詞標識符)。
下面的例子說明Xid的實現:
import javax.transaction.xa.*;
public class MyXid implements Xid
{
protected int formatId;
protected byte gtrid[];
protected byte bqual[];
public MyXid()
{
}
public MyXid(int formatId, byte gtrid[], byte bqual[])
{
this.formatId = formatId;
this.gtrid = gtrid;
this.bqual = bqual;
}
public int getFormatId()
{
return formatId;
}
public byte[] getBranchQualifier()
{
return bqual;
}
public byte[] getGlobalTransactionId()
{
return gtrid;
}
}
其次,你需要創建一個你要使用的資料庫的數據源:
public DataSource getDataSource()
throws SQLException
{
SQLServerDataSource xaDS = new
com.merant.datadirect.jdbcx.sqlserver.SQLServerDataSource();
xaDS.setDataSourceName("SQLServer");
xaDS.setServerName("server");
xaDS.setPortNumber(1433);
xaDS.setSelectMethod("cursor");
return xaDS;
}
例1 這個例子是用「兩步提交協議」來提交一個事務分支:
XADataSource xaDS;
XAConnection xaCon;
XAResource xaRes;
Xid xid;
Connection con;
Statement stmt;
int ret;
xaDS = getDataSource();
xaCon = xaDS.getXAConnection("jdbc_user", "jdbc_password");
xaRes = xaCon.getXAResource();
con = xaCon.getConnection();
stmt = con.createStatement();
xid = new MyXid(100, new byte[]{0x01}, new byte[]{0x02});
try {
xaRes.start(xid, XAResource.TMNOFLAGS);
stmt.executeUpdate("insert into test_table values (100)");
xaRes.end(xid, XAResource.TMSUCCESS);
ret = xaRes.prepare(xid);
if (ret == XAResource.XA_OK) {
xaRes.commit(xid, false);
}
}
catch (XAException e) {
e.printStackTrace();
}
finally {
stmt.close();
con.close();
xaCon.close();
}
當然,實際過程中,我們不需要寫這些代碼,這些代碼是JTA最終的實現代碼。
關於「兩步提交協議」,可以參看下面的文章:
http://www.ibm.com/developerworks/cn/db2/library/techarticles/dm-0505weber/index.html
兩階段提交(Two-Phase-Commit)協議
首先,兩階段提交(Two-Phase-Commit)事務的啟動與常規的單階段提交(One-Phase-Commit)事務類似。接著,應用程序/客 戶機對該兩階段提交(Two-Phase-Commit)操作中所涉及的所有資料庫執行其修改工作。現在,在最終提交該事務之前,客戶機通知參與的資料庫准備提交(第 1 階段)。如果客戶機從資料庫收到一條「okay」,就發出命令向資料庫提交該事務(第 2 階段)。最後分布式事務(Distributed Transaction)結束。
上面的例子演示了如何在 Java 中使用 JTA 實現兩階段提交(Two-Phase-Commit)協議。在該應用程序中,如果一個事務分支報告了錯誤,您就要負責進行錯誤處理。但是「兩階段提交協議 簡介」小節中提到仍然存在一個問題,那就是如果第 2 階段中一個事務分支發生故障,該怎麼辦呢?
如果再次查看程序代碼,您可以看到在「第 1 階段」和「第 2 階段」之間有一個很小的時間間隔。在這一時間間隔中,出於某種理由,其中某一參與資料庫可能崩潰。如果發生了,我們將陷入分布式事務已經部分提交的情形中。
假 定下列情形:在「第 1 階段」之後,您從 DB2 和 IDS 資料庫中都收到了「okay」。在下一步中,應用程序成功提交了 DB2 的事務分支。接著,應用程序通知 DB2 事務分支提交事務。現在,在應用程序可以通知 IDS 事務分支提交它這一部分之前,IDS 引擎由於斷電發生崩潰。這就是一種部分提交全局事務的情形。您現在該怎麼辦呢?
在重啟之後,DB2 和 IDS 都將嘗試恢復打開的事務分支。該引擎等待來自應用程序的提示如何做。如果應用程序沒有準備重新發送「第 2 階段」的提交,該事務分支將被引擎所啟動的試探性回滾中止。這是非常糟糕的,因為這將使該全局事務處於不一致狀態。
一種解決方案是用一個小型應用程序連接引擎中打開的事務分支,並通知引擎提交或回滾這一打開的事務。如果您使用 IDS 作為後端,那麼還有一個隱藏的 onmode 標志,允許您結束打開的事務分支。(onmode -Z xid)。
在 DB2 UDB 中,您可以發出 LIST INDOUBT TRANSACTIONS 來獲得打開的 XA 事務的有關信息。您必須查看 DB2 Information Center 中的描述來解決該問題。
上面描述的情形是一個很好的例子,也是使用應用程序伺服器(Application Server)或事務監控器(Transaction Monitor)的理由。在使用一個中間層伺服器時,就由該伺服器負責保持事情正常。
Ⅶ 關於jdbc中資料庫事務的提交和回滾
首先,連接資料庫異常,可能是資料庫JDBC連接問題,也可能是驅動問題。
第二,沒找到資料庫
第三,資料庫欄位拼寫錯誤。
第四,SQL語句錯誤
第五,還沒發現。呵呵。這個是我最近2天遇到的問題。。。都在這里啦。。
Ⅷ JDBC事物回滾怎麼不起作用
JDBC 事務不回滾?
有兩種情況,先看 autoCommit(true),在JDBC規范中有這樣一段描述:
Newly created Connection objects are in auto-commit mode by default, which means that indivial SQL statements are committed automatically when the statement is completed.
可看出,只要你的SQL 本身沒有問題,JDBC就會自動提交,但是比如接入數據發生異常,拋出SQLException的時候事務不會回滾的。
所有通常會手工控制,但是這里還有一個坑,就是有些數據源,會使用代理模式,將真正的Connection 包裹起來(依據架構和組件的不同,可能會有很多層包裹),你需要getMeterConnection 後,在對元Connection設置AutoCommit ,否則無論你怎麼寫,輕者異常,重者不通知成為「懸案」。
如果你使用了JTA,事務不回滾,依然正常,JTA 不是所有的異常都回滾的,只有對unCheckException 才回滾,換句話說,只有對RuntimeException 或其子異常才回滾。
Ⅸ JDBC調用存儲過程,存儲過程中事務回滾,報錯
ConnCloseThread中關閉連接的時候,不是立刻返回的。Connection.close()會觸發Connection.commit(),而因為調用的存儲過程中,存儲過程起了自己的事務,connection.commit()必須等到存儲過程結束才能完成(這個是microsoft論壇上看到的)。如果所有connection.close()都等到tx commit或rollback完成才執行的話,這個問題就不會出現了
從測試結果來看,凡是close connection耗時比execute statement短的,連接(物理連接)都會報出該問題。分析原因:通過weblogic datasource獲取的connection並不是物理connection,而是由weblogic wrapped的connection。這些conection在被close後,並不會關閉物理連接,而只是將物理連接還池。我們對connection的所有操作,最終都會被delegated到底層物理連接上,即commit(),rollback()最終都是在物理連接上執行。如果上面的connection.close(),底層物理連接沒有等到存儲過程事務結束就返回的話,那麼物理連接上應該還帶有此次操作的事務,而weblogic這邊不會關系物理連接的情況,直接將連接放入connection pool供其它客戶端使用。這時候如果設定了test on reserve的話,下次客戶端從data source獲取連接時,weblogic會檢查這個物理連接,作一個select操作的,這個有問題的連接就會暴露出來,也就是上面的異常。這個問題如果使用driver manager來獲取連接的話(如果每次都關閉的話),則不會出現,因為使用的物理連接每次都是不同的。還好,weblogic會幫忙重新創建有問題的連接。原因大概了解了,但這是誰的問題呢? 為什麼connection.close()不等存儲過程的事務結束?
結論:一般而言,我們不建議通過JDBC調用存儲過程的時候,在存儲過程中定義事務,應該將tx的管理工作交給jdbc去做。 non-xa如此,xa亦如此,畢竟事務嵌套了以後,管理起來是個問題,完整性更是個問題。
Ⅹ jdbc 事務處理問題 提交 回滾
try {
conn =
DriverManager.getConnection("jdbc:oracle:thin:@host:1521:SID","username","userpwd";
conn.setAutoCommit(false);//禁止自動提交,設置回滾點
stmt = conn.createStatement();
stmt.executeUpdate(「insert into table …」);
stmt.executeUpdate(「delete from table …」);
conn.commit(); //事務提交
}catch(Exception ex) {
ex.printStackTrace();
try {
conn.rollback(); //操作不成功則回滾
}catch(Exception e) {
e.printStackTrace();
}
}