zoukankan      html  css  js  c++  java
  • JDBC Tutorials: Commit or Rollback transaction in finally block

    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 theTransactions 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...
    }
    }
    }
  • 相关阅读:
    KVC之-setValue:forKey:方法实现原理与验证
    李洪强iOS开发之iOS社区收集
    跟着百度学PHP[15]-会话控制session的工作机制
    代码审计学习之文件操作漏洞
    中间人攻击——ARP欺骗的原理、实战及防御
    跟着百度学PHP[14]-PDO的预处理语句2
    跟着百度学PHP[14]-PDO的预处理语句1
    跟着百度学PHP[14]-PDO之Mysql的事务处理2
    跟着百度学PHP[14]-PDO之Mysql的事务处理1
    跟着百度学PHP[14]-PDO的错误处理模式&PDO执行SQL
  • 原文地址:https://www.cnblogs.com/kungfupanda/p/5898547.html
Copyright © 2011-2022 走看看