• jdbc java数据库连接 9)事务编程


    1. 事务

    基本概念:

    事务使指一组最小逻辑操作单元,里面有多个操作组成。 组成事务的每一部分必须要同时提交成功,如果有一个操作失败,整个操作就回滚。

    事务ACID特性:

      l 原子性(Atomicity

        原子性是指事务是一个不可分割的工作单位,事务中的操作要么都发生,要么都不发生。 

      l 一致性(Consistency

        事务必须使数据库从一个一致性状态变换到另外一个一致性状态。

      l 隔离性(Isolation

        事务的隔离性是多个用户并发访问数据库时,数据库为每一个用户开启的事务,不能被其他事务的操作数据所干扰,多个并发事务之间要相互隔离。

      l 持久性(Durability

        持久性是指一个事务一旦被提交,它对数据库中数据的改变就是永久性的,接下来即使数据库发生故障也不应该对其有任何影响

    案例

      需求 张三给李四转账

      设计 账户表

      技术

          |-- Connection

        1. void setAutoCommit(boolean autoCommit) ;  设置事务是否自动提交,如果设置为false,表示手动提交事务。
        2. void commit() ();   手动提交事务
        3. void rollback() ;   回滚(出现异常时候,所有已经执行成功的代码需要回退到事务开始前的状态。)
        4. Savepoint setSavepoint(String name) :savepoint - 要回滚到的 Savepoint 对象 

        1:sql代码,账目表:

    1 CREATE TABLE transfer(
    2     id INT PRIMARY KEY AUTO_INCREMENT ,
    3     accName VARCHAR(20),
    4     accmoney DOUBLE
    5 )

        2:设定事务,若事务中有语句出现错误,则回滚到事务的初始化

     1 /**
     2  * 这是个事务的操作类
     3  * 
     4  * @author LZL
     5  * 
     6  */
     7 public class Connection_false {
     8 
     9     // 设定全局变量
    10     private static Connection conn;
    11     private static PreparedStatement stsm;
    12 
    13     /**
    14      * 这是个出错就回滚回整个事务的起始未知的例子
    15      */
    16 
    17     @Test
    18     public void trans1() {
    19 
    20         // 1:准备sql语言
    21         String sql1 = "UPDATE transfer SET accmoney=accmoney-1000 WHERE accName='张三';";
    22         String sql2 = "UPDATE transfer SET accmoney=accmoney+1000 WHERE accName='李四';";
    23 
    24         try {
    25             // 2:创建连接
    26             conn = Jdbcutil.getConnection();
    27 
    28             // 3:设定事物为手动开启
    29             // void setAutoCommit(boolean autoCommit):将此连接的自动提交模式设置为给定状态
    30             conn.setAutoCommit(false);
    31 
    32             // 4:执行sql
    33             stsm = conn.prepareStatement(sql1);
    34             stsm.executeUpdate();
    35 
    36             stsm = conn.prepareStatement(sql2);
    37             stsm.executeUpdate();
    38 
    39         } catch (Exception e) {
    40             // 4:若是上面的语句有任何一条出错,则回滚事务
    41             try {
    42                 conn.rollback();
    43             } catch (Exception e1) {
    44                 e1.printStackTrace();
    45             }
    46         } finally {
    47             // 4:若是上面的语句(事务)都没错,则执行事务
    48             // void commit():使所有上一次提交/回滚后进行的更改成为持久更改,并释放此 Connection
    49             // 对象当前持有的所有数据库锁。
    50             try {
    51                 conn.commit();
    52                 // 5:关闭连接
    53                 Jdbcutil.close(conn, stsm);
    54             } catch (Exception e) {
    55                 e.printStackTrace();
    56             }
    57 
    58         }
    59     }

        

        3:这是个回滚到事务中的指定位置的方法 例:如果我知道第一笔转账肯定成功,若出错就只会是第二笔出错,所以我会在第一和第二之间的位置设定个保存点:
          Savepoint setSavepoint(String name) 在当前事务中创建一个具有给定名称的保存点
          然后若是出错,则回滚到该保存点的位置,而之前的语句仍正常执行 void rollback(Savepoint savepoint):
           savepoint - 要回滚到的 Savepoint 对象

     1 @Test
     2     public void test2() {
     3 
     4         // 创建保存点对象
     5         Savepoint one = null;
     6 
     7         // 1:设定sql语句
     8         // 第一次转账
     9         String one1 = "UPDATE transfer SET accmoney=accmoney-1000 WHERE accName='张三';";
    10         String one2 = "UPDATE transfer SET accmoney=accmoney+1000 WHERE accName='李四';";
    11         // 第二次转账
    12         String two1 = "UPDATE transfer SET accmoney=accmoney-1000 WHERE accName='张三';";
    13         String two2 = "UPDATE tranfer SET accmoney=accmoney+1000 WHERE accName='李四';";
    14 
    15         try {
    16             // 2:创建连接
    17             conn = Jdbcutil.getConnection();
    18 
    19             // 3:设定事务为手动执行
    20             conn.setAutoCommit(false);
    21 
    22             // 4:创建PreparedStatement对象。执行sql语句
    23             // 执行第一笔转账
    24             stsm = conn.prepareStatement(one1);
    25             stsm.executeUpdate();
    26             stsm = conn.prepareStatement(one2);
    27             stsm.executeUpdate();
    28 
    29             // 5:设定保存点
    30             one = conn.setSavepoint("one");
    31 
    32             // 执行第二笔转账
    33             stsm = conn.prepareStatement(two1);
    34             stsm.executeUpdate();
    35             stsm = conn.prepareStatement(two2);
    36             stsm.executeUpdate();
    37 
    38         } catch (Exception e) {
    39             // 6:若有语句出错,则回滚到保存点
    40             try {
    41                 conn.rollback(one);
    42             } catch (Exception e1) {
    43                 e1.printStackTrace();
    44             }
    45             e.printStackTrace();
    46         } finally {
    47             try {
    48                 // 7:若语句没有错误,则执行事务
    49                 conn.commit();
    50                 // 8:关闭连接
    51                 Jdbcutil.close(conn, stsm);
    52             } catch (Exception e) {
    53                 e.printStackTrace();
    54             }
    55         }
    56 
    57     }
  • 相关阅读:
    组合,封装与多态
    继承与派生
    面向对象基础练习
    面向对象基础
    类与对象
    数组与pandas模块
    Flask基础(15)-->模板代码的复用【宏(Macro)、继承(Block)、包含(include)】
    Flask基础(14)-->自定义过滤器
    Flask基础(13)-->Flask扩展Flask-Script
    Flask基础(12)-->请求上下文和应用上下文
  • 原文地址:https://www.cnblogs.com/LZL-student/p/6021183.html
Copyright © 2020-2023  润新知