zoukankan      html  css  js  c++  java
  • JDBC事务与保存点 JDBC简介(七)

    事务简介

    数据库事务(Database Transaction) ,是指作为单个逻辑工作单元执行的一系列操作,要么完全地执行,要么完全地不执行。
    事务是必须满足4个条件(ACID)
    • 事务的原子性( Atomicity)一组事务,要么全部成功;要么全部失败。
    • 一致性 (Consistency):事务在完成时,必须使所有的数据都保持一致状态。在相关数据库中,所有规则都必须应用于事务的修改,以保持所有数据的完整性。比如一个学生表中新插入了一条记录,这个学生的class_id必须是一个已经存在的正确的,A账户向B账户转账,不能出现负数,如果不做任何保障,出现了负数,这就是破坏了一致性可以认为是一致性表示数据本来是正确的,经过了事务,转换为了另外的一个状态,仍旧是正确的。
    • 隔离性(Isolation):由并发事务所作的修改必须与任何其它并发事务所作的修改隔离。也就是说另一并发事务要么读取的是事务前的状态,要么是事务后的状态,不会是这个事务的中间状态。
    • 持久性(Durability):事务完成之后,它对于系统的影响是永久性的。该修改即使出现致命的系统故障也将一直保持。
     
    在默认情况下,MySQL每执行一条SQL语句,都是一个单独的事务
    如果需要将多条SQL语句设在在同一个事务中,那么需要开启事务和结束事务
    JDBC中与事务有关的方法
    Connection与事务有关的主要方法:
    • setAutoCommit(boolean):设置是否为自动提交事务,如果true(默认值为true)表示自动提交,也就是每条执行的SQL语句都是一个单独的事务;如果设置为false,那么相当于开启了事务,con.setAutoCommit(false) 表示开启事务。
    • commit():提交结束事务。
    • rollback():回滚结束事务。
    • setSavepoint():设置保存点。

    事务使用示例

    package jdbc;
    import java.sql.Connection;
    import java.sql.DriverManager;
    import java.sql.ResultSet;
    import java.sql.Statement;
    public class MyTransactional {
    public static void main(String[] args) throws Exception{
        String user = "root";
        String password = "123456";
        String url = "jdbc:mysql://localhost:3306/sampledb?useUnicode=true&characterEncoding=utf-8";
        //2、获取连接对象
        Connection conn = DriverManager.getConnection(url, user, password);
        String sql = "delete from student where id='59'";
        //2、获得sql语句执行对象
        Statement stmt = conn.createStatement();
        conn.setAutoCommit(false);
        //3、执行并保存结果集
        int rows = stmt.executeUpdate(sql);
        System.out.println("受影响的行: "+rows);
        conn.commit();
        // conn.rollback();
        conn.close();
        stmt.close();
    }
    }
    在执行前开启事务,conn.setAutoCommit(false);
    注意:一定是执行前
    只有开启事务和结束事务之间的执行才属于这个事务,如果像下面这样,可以认为是两个事务,前面一个自动提交了,然后开启了新的事务,然后回滚了新的事务
        stmt.executeUpdate(sql);
        conn.setAutoCommit(false);
        conn.rollback();
    最终通过commit或者rollback 结束事务。
    通常的一个使用形式为:
    try {
    con = DBConnection.getConnection();
    //开启事务
    con.setAutoCommit(false);
    
    //处理业务逻辑
    
    //提交事务
    con.commit();
    }
    catch (SQLException e) {
    e.printStackTrace();
    //出现异常,回滚事务
    try {
    con.rollback();
    System.out.println("JDBC Transaction rolled back successfully");
    }
    catch (SQLException e1) {
    System.out.println("SQLException in rollback" + e.getMessage());
    }
    }

    保存点

    有的时候可能并不需要将一整个事务进行回滚,一个复杂的事务可能由几个一致性的阶段组成
    保存点就是在一个事务中,插入几个还原点,再出现问题时,可以及时的撤回到这个地方来
    当撤回到一个还原点时,事务还在,仍在进行中,所以还需要再次的COMMIT,这次的COMMIT,保存点以下的执行相当于不存在。

     

    package jdbc;
    import java.sql.Connection;
    import java.sql.DriverManager;
    import java.sql.ResultSet;
    import java.sql.Savepoint;
    import java.sql.Statement;
    public class MyTransactional {
    public static void main(String[] args) throws Exception{
        String user = "root";
        String password = "123456";
        String url = "jdbc:mysql://localhost:3306/sampledb?useUnicode=true&characterEncoding=utf-8";
        //2、获取连接对象
        Connection conn = DriverManager.getConnection(url, user, password);
        conn.setAutoCommit(false);
        String sql1 = "delete from student where id='158'";
        String sql2 = "delete from student where id='159'";
        //2、获得sql语句执行对象
        Statement stmt = conn.createStatement();
        //3、执行并保存结果集
        stmt.executeUpdate(sql1);
        Savepoint savepoint1 = conn.setSavepoint("savepoint1");
        stmt.executeUpdate(sql2);
        Savepoint savepoint2 = conn.setSavepoint("savepoint2");
        conn.rollback(savepoint1);
        conn.commit();
        // conn.rollback();
        conn.close();
        stmt.close();
    }
    }
    上面的示例中,执行了两次删除,删除id=158时,创建保存点savepoint1;删除id=159时,创建保存点savepoint2
    将事务回滚到保存点1 conn.rollback(savepoint1);,然后进行提及,保存点savepoint1以上的部分成功提交,后面的部分没有提交
    也就是回滚到哪个保存点,那个保存点以下就相当于不存在
    image_5c491b65_599e
    保存点就是这样将一整个完整的过程进行了拆分,rollback到哪个保存点,哪个保存点以下就会回滚,之前的就会提交
    一定要注意: conn.rollback(savepoint1); 并不会结束事务,只有 conn.commit();或者 conn.rollback();方法才会结束事务。
    image_5c491b65_3436
  • 相关阅读:
    LeetCode【709. 转换成小写字母】
    静态方法、变量与实例方法、变量之比较心得
    用户控件自定义 DependencyProperty 属性使用教程
    TypeLoadException: 未能从程序集“ECS.GUI.Define, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null”中加载类型“ECS.GUI.Define.ArmgAimPos”,因为它在 4 偏移位置处包含一个对象字段,该字段已由一个非对象字段不正确地对齐或重叠
    ABP 框架实战系列(三)-领域层深入篇
    ABP 框架实战系列(二)- 领域层介绍篇
    ABP框架实战系列(一)-持久层介绍篇
    EF Core 基础知识
    EF Core Migration 报错:An error occurred using the connection to database '' on server '10.28.253.2'
    2020年总结:互联网思维下的工业软件开发
  • 原文地址:https://www.cnblogs.com/noteless/p/10312824.html
Copyright © 2011-2022 走看看