Java学习者论坛

 找回密码
 立即注册

QQ登录

只需一步,快速开始

手机号码,快捷登录

恭喜Java学习者论坛(https://www.javaxxz.com)已经为数万Java学习者服务超过8年了!积累会员资料超过10000G+
成为本站VIP会员,下载本站10000G+会员资源,购买链接:点击进入购买VIP会员
JAVA高级面试进阶视频教程Java架构师系统进阶VIP课程

分布式高可用全栈开发微服务教程

Go语言视频零基础入门到精通

Java架构师3期(课件+源码)

Java开发全终端实战租房项目视频教程

SpringBoot2.X入门到高级使用教程

大数据培训第六期全套视频教程

深度学习(CNN RNN GAN)算法原理

Java亿级流量电商系统视频教程

互联网架构师视频教程

年薪50万Spark2.0从入门到精通

年薪50万!人工智能学习路线教程

年薪50万!大数据从入门到精通学习路线年薪50万!机器学习入门到精通视频教程
仿小米商城类app和小程序视频教程深度学习数据分析基础到实战最新黑马javaEE2.1就业课程从 0到JVM实战高手教程 MySQL入门到精通教程
查看: 396|回复: 0

[JDBC学习]灵活地回滚事务

[复制链接]
  • TA的每日心情
    开心
    2021-3-12 23:18
  • 签到天数: 2 天

    [LV.1]初来乍到

    发表于 2014-10-10 23:54:35 | 显示全部楼层 |阅读模式
    JDBC 3.0的savepoints可以让你细化地控制一个数据库事务。
    by Sameer Tyagi  
          JDBC 3.0的一个最酷的新功能就是它可以在一个事务中创建并运用savepoints。Savepoints――长期以来是SQL的一个功能――通过标记事务可以回滚到的中间步骤,就可以让你细化地控制一个JDBC数据库事务。

      

      
      
       
       
       

       
       
           那么你为什么要这么做呢?我们来看一个典型的订票问题。Ivana女士想从Boston到Cancun度假,然后再回来。她订的票是从Boston到New York,再到Cancun的,然后再返回,因为没有从Boston到Cancun的直航。下面就是整个事务的步骤:

      1. 开始事务  

      2. 订从Boston到NY的航班  

      3. 订从NY到Cancun的航班  

      4. 订从Cancun到NY的返航  

      5. 订从NY到Boston的返航  

      6. 提交事务  
      7. 如果出现异常或错误,回滚事务  
      
      
      
         但在这个例子中,如果在第五步,票售完了,整个行程就得取消,回滚使数据库回复到第一步开始执行前的状态。然而,不管怎样Ivana可能还是需要一些票的,因为她可以在返回时坐另外的航线。你可以用JDBC 3.0的savepoints来帮助Ivana女士,整个事务如下:  
      1. 开始事务  
      2. 订从Boston到NY的航班  
      3. 订从NY到Cancun的航班  
      4. 建立savepoint  
      5. 订从Cancun到NY的返航  
      6. 订从NY到Boston的返航  
      7. 当出现异常或错误时,如果设了savepoint,回滚事务到步骤4中的savepoint  
      8. 提交事务  

         简单地说,一个savepoint就是代表一个特殊时间点上的一个事务,并对事务中SQL语句的一个子集完成的工作提供细化的控制。运用savepoint,你就不会回滚到一个事务的起始状态,而是回滚到savepoint。你可以在一个单一的事务中运用多个savepoints,通过明确调用Connection.releaseSavepoint (savepoint) 方法,或者通过提交事务、回滚整个事务来释放(release)savepoints。一旦一个savepoint被释放了,试图回滚到它就会抛出一个SQLException异常。

    要在你的java代码中运用savepoints,你必须运用JDBC 3.0,这就是说:
      ・ 你必须运用JDK 1.4,因为它是一个核心API。  
      ・ 你的JDBC驱动程序必须是JDBC 3.0兼容的。你可以在http://industry.java.sun.com/products/jdbc/drivers的Sun JDBC驱动程序数据库中找到JDBC驱动程序列表。  

         样例代码的结果显示了JDBC中的savepoint如何与SQL savepoint相应,而且事务是如何回滚到savepoint的(见列表1和图1)。当然,你可以用其它的方法来解决订票问题,比如把事务分成多个事务。但是savepoints是个很好的方法,它可以让你不用处理许多不同的事务。


    关于作者:
    Sameer Tyagi是Sun Microsystems的Enterprise Java Architect(企业Java架构师),他定期为在线和印刷刊物撰稿。Sameer的联系方式是Sameer.Tyagi@Sun.com。

    样例程序:

    import java.sql.*;   

    public class SavepointDemo {

             private static Connection connection;
             private static  Statement stmt ;
             private static  boolean forseoneway=false;
             private static  Savepoint txpoint;


    public static void main (String args[]) throws Exception {
             if (args.length < 4 ){
                      System.out.println("Usage java SavepointDemo driverclass username password url forseoneway");
                      return;
                      }


            try {
             String driver = args[0];
             String username= args[1];
             String password= args[2];
             String url= args[3];
             if ((args.length ==5) &&(args[4]!=null))
                        forseoneway=  new Boolean (args[4]).booleanValue();
             Class.forName(driver).newInstance();
             connection = DriverManager.getConnection(url,username,password);
             DriverManager.setLogStream(System.out); // for debuging
             connection.setAutoCommit(false);
             //create a statement
             stmt = connection.createStatement();
             //execute a query
             stmt.executeUpdate("insert into tickets values ("ivana", "NY", "BOSTON", &#3911;-July-2002", &#399;:00 AM", "Delta 782")");
             stmt.executeUpdate("insert into tickets values ("ivana", "BOSTON", "CANCUN", &#3911;-July-2002", &#3912;:00 PM", "Delta 819")");
             txpoint = connection.setSavepoint("oneway"); // establish a save point

             stmt.executeUpdate("insert into tickets values ("ivana", "CANCUN", "NY", &#3912;-August-2002", &#392;:00 PM", "Delta 820")");
             stmt.executeUpdate("insert into tickets values ("ivana", "NY", "BOSTON", &#3912;-August-2002", &#396;:00 PM", "Delta 783")");

              // for demo purposes in case there are no exceptions
              if (forseoneway && (txpoint != null) )
                       connection.rollback(txpoint);  
              connection.commit();
           } catch(Exception e) {
                   System.out.println(e);
                   if (txpoint != null ){
                          connection.rollback(txpoint);
                          connection.commit();
                   } else  
                          connection.rollback();
           }finally {// clean up everything
                          if (stmt != null)
                                stmt.close();
                          if (connection != null)
                                connection.close();
                          }// end finally

           }// end main method
    }// end class

      

      
      
       
       

         
       

         
       
      


      

      



                            function TempSave(ElementID)
                            {
                                    CommentsPersistDiv.setAttribute("CommentContent",document.getElementById(ElementID).value);
                                    CommentsPersistDiv.save("CommentXMLStore");
                            }
                            function Restore(ElementID)
                            {
                                    CommentsPersistDiv.load("CommentXMLStore");
                                    document.getElementById(ElementID).value=CommentsPersistDiv.getAttribute("CommentContent");
                            }
    回复

    使用道具 举报

    您需要登录后才可以回帖 登录 | 立即注册

    本版积分规则

    QQ|手机版|Java学习者论坛 ( 声明:本站资料整理自互联网,用于Java学习者交流学习使用,对资料版权不负任何法律责任,若有侵权请及时联系客服屏蔽删除 )

    GMT+8, 2025-2-26 13:32 , Processed in 0.365367 second(s), 50 queries .

    Powered by Discuz! X3.4

    © 2001-2017 Comsenz Inc.

    快速回复 返回顶部 返回列表