JDBC Tutorials: Commit or Rollback transaction in finally block

探讨了在JDBC中使用try-catch-finally块进行事务管理的最佳实践。文章指出,仅捕获SQLException不足以确保数据一致性,应捕获所有异常,并在finally块中决定提交或回滚,以避免数据完整性问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

http://skeletoncoder.blogspot.com/2006/10/jdbc-tutorials-commit-or-rollback.html

 

JDBC Tutorials: Commit or Rollback transaction in finally block

 

In most of JDBC books, the transaction management idiom that is followed is, after executing the update statements commit, and if an SQLException is thrown, rollback.
That is,


Connection con = null;
try{
con = //...
con.setAutoCommit(false);

Statement stmt1 = ...
stmt1.executeUpdate();

// Some operations

Statement stmt2 = ...
stmt2.executeUpdate();

con.commit();
con.setAutoCommit(true);
}catch(SQLException e){
if(con!=null){
try{
con.rollback();
}catch(SQLException e){
// Log the error...
}
}
}


The similar structure is followed in the  JDBC(TM) API
Tutorial and Reference
 from the Sun Microsystems. Have a look at the Transactions Tutorial and the  Sample code provided.

There is a severe problem with this way of commiting and rollback. The problem is we are handling only the SQLException. What will happen if a RuntimeException occured after executing the first update statement but beforethe second update statement?

The transaction is opened, but neither commited nor rolled back. This will leave the data integrity into trouble. If we are reusing the same connection (as in most cases), and we commit the transaction in the next statements, we are into serious trouble. We have inconsitent data.

What is the solution?
Catch Exception instead of SQLException
A simpler and not recommended solution is, catch all the execeptions, including RuntimeException. Even now, what if an Error is thrown, say OutOfMemoryError or some VirtualMachineError or something else? What ever happens in the code, we should either the database should be committed or rolledback. So, the worst thing is we should catch the Throwable class, instead of Exception.

Doesn't this look awkward,Whenever we use transactions we should catch a Throwable class or atleast Exception class?

Use finally block
A clean solution and yet simple solution is, use finally block. Since it is always guaranteed that the finally block will be executed even when any Exception is thrown or even when the method is returned.



Connection con = null;
boolean success = false;
try{
con = //...
con.setAutoCommit(false);

Statement stmt1 = ...
stmt1.executeUpdate();

// Some operations

Statement stmt2 = ...
stmt2.executeUpdate();

success = true;

}catch(SQLException e){
success = false;
}finally{
if(con!=null){
try{
if(success){
con.commit();
con.setAutoCommit(true);
}else{
con.rollback();
}
}catch(SQLException e){
// Log the error...
}
}
}

 

转载于:https://www.cnblogs.com/kungfupanda/p/5898547.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值