• 事务提交 commit 会失败么_事务的四大特性ACID


    https://blog.csdn.net/weixin_39755136/article/details/111281765

    eba4101a6d3ea5eb6a9055354aae27eb.png

    相关历史文章(阅读本文之前,您可能需要先看下之前的系列?)

    分布式事务「2020年」必学,升职加薪你准备好了吗?

    事务的基本概念

    前言

           对于要把事务在实际中使用好,需要了解事务的特性。

           事务的四大特性主要是:原子性(Atomicity)、一致性(Consistency)、隔离性(Isolation)、持久性(Durability)。

    一、事务的四大特性

    1.1 原子性(Atomicity)

    原子性是指事务是一个不可分割的工作单位,事务中的操作要么全部成功,要么全部失败。比如在同一个事务中的SQL语句,要么全部执行成功,要么全部执行失败。

    begin transaction;
        update account set money = money-100 where name = '张三';
        update account set money = money+100 where name = '李四';
    commit transaction;

    1.2 一致性(Consistency)

    官网上事务一致性的概念是:事务必须使数据库从一个一致性状态变换到另外一个一致性状态。

           换一种方式理解就是:事务按照预期生效,数据的状态是预期的状态。

           举例说明:张三向李四转100元,转账前和转账后的数据是正确的状态,这就叫一致性,如果出现张三转出100元,李四账号没有增加100元这就出现了数据错误,就没有达到一致性。

    1.3 隔离性(Isolation)

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

    1.4 持久性(Durability)

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

           例如我们在使用JDBC操作数据库时,在提交事务方法后,提示用户事务操作完成,当我们程序执行完成直到看到提示后,就可以认定事务以及正确提交,即使这时候数据库出现了问题,也必须要将我们的事务完全执行完成,否则就会造成我们看到提示事务处理完毕,但是数据库因为故障而没有执行事务的重大错误。

    二、数据库ACID的体现

    2.1 原子性

           原子性说的是数据要么一起成功,要么一起失败,那么就有两种情况:事务提交(commit)和事务回滚(rollback)。

           我们先看下事务正常提交的情况,下面我们在数据库模拟张三给李四转账成功的场景:

    6a17c034ff5becc3a408dfd7a6d1d0a1.png

    我们手动提交(commit)数据库事务之后,张三给李四转账100元的这个业务操作算是真正成功了,张三账户中少了100,李四账户中多了100。

           接下来看下事务不正常的情况下:

    82a799f42259f83e31ccd2de66bb7e7c.png

           事务回滚之后,对于张三和李四的金额的操作都失败了,这就确保了事务的原子性。

    2.2 一致性

           一致性主要说明的是事务的前后,数据库中的数据的状态要确保一致。

    事务提交成功,那么张三账户上的余额是900元,李四账户上的余额是100元。

    事务提交失败,那么张三和李四的账户的金额不变。

           这说明现在在数据库的事务的控制下,确保了数据的一致性。

    2.3 隔离性

           隔离性的体现,多个并发事务之间是隔离的。

           张三给李四转账,如果事务没有提交的话,那么在另外一个session中并不能查看另外一个session未提交的数据。

    4865e46458be149c1c6f500a402e030e.png

    2.4 持久性

           持久性的体现就是数据一旦commit之后,那么对于数据的改变就是永久的。我们commit之后,张三的账户就永久减少了100元,李四的账户就永久增加了100元。

    三、JDBC ACID的体现

           我们使用JDBC连接MYSQL数据库的代码:

    public class App {
        public static void main(String[] args) throws ClassNotFoundException, SQLException {
            /*
             * 1/ 注册JDBC驱动; 
             * 2/ 获取连接; 
             * 3/ 开启事务
             * 4/ 创建SQL语句; 
             * 5/ 执行SQL语句; 
             * 6/ 提交事务
             * 7/ 关闭连接.
             * 
             */
            // 1/ 注册JDBC驱动;
            Class.forName("com.mysql.cj.jdbc.Driver");

            String url = "jdbc:mysql://127.0.0.1:3306/tx_demo";
            String user = "root";
            String password = "root";

            // 2/ 获取连接;
            Connection conn = DriverManager.getConnection(url, user, password);

            // 3/ 开启事务
            conn.setAutoCommit(false);

            // 4/ 创建SQL语句; 注意:实际使用account的主键,这里主要是为了方便理解。
            String sql = "update account set money = money-100 where name = ?";
            PreparedStatement ps = conn.prepareStatement(sql);
            ps.setString(1,"张三");

            // 5/ 执行SQL语句; 
            int rs = ps.executeUpdate();
            if(rs>0) {
                System.out.println("张三-扣减成功");
            }

            // 给李四增加金额
            sql = "update account set money = money+100 where name = ?";
            ps = conn.prepareStatement(sql);
            ps.setString(1,"李四");
            rs = ps.executeUpdate();
            if(rs>0) {
                System.out.println("李四-增加成功");
            }

            // 6/ 提交事务,更标准的写法应该拦截异常,有异常的情况下rollback();
            conn.commit();

            // 7/ 关闭连接.
            ps.close();
            conn.close();
        }
    }

    说明:

    如果代码正常运行的话,那么张三会扣减金额,李四会增加金额,这就确保的原子性;

     一旦数据保存到数据库之后,数据就永久被改变了,这就是持久性;

    事务前后,数据的状态也是我们所期望的状态,这就保证了数据的一致性;

    如果在事务未commit的话,那么在另外一个线程发起查询请求的话,那么并不能查看到最近的数据(这里未进行编码),这就是隔离性。

    分布式事务解决方案「手写代码」:http://t.cn/AieNUirK

    点击「

  • 相关阅读:
    python基础之函数v1
    Python之基础函数
    python 文件操作之指针v1
    python 文件之指针操作
    文件操作
    Eclipse报错:添加server tomcat8.0 The Apache Tomcat installation at this directory is version 8.5.43. A Tomcat 8.0 installation is expected.
    Eclipse报错:pom.xml第一行org.apache.maven.archiver.MavenArchiver.getManifest(org.apache.maven.project.MavenProject, org.apache.maven.archiver.MavenArchiveConfiguration) pom.xml /xxx line 1 Maven Config
    React Native开发IDE之WebStorm安装及配置(Windows)
    React Native 报错:Unable to load script from assets 'index.android.bundle'
    React Native 报错:The module `./index.android` could not be found from
  • 原文地址:https://www.cnblogs.com/sunny3158/p/14686628.html
Copyright © 2020-2023  润新知