美文网首页
数据库事务

数据库事务

作者: Always_July | 来源:发表于2021-11-12 22:51 被阅读0次

    ACID

    Atomicity

    原子性,一次事务中的操作要么全部成功,要么全部失败。

    Consistency

    一致性,事务的一致性是指事务不能破坏数据库数据的完整性和一致性,一个事务在执行之前和执行之后,数据库都必须处于一致性的状态。也就是说,事务执行的结果必须是使数据库从一个一致性状态转变到另一个一致性状态,因此当数据库只包含成功数事务提交的结果时,就能说数据库处于一致性状态。而如果数据库系统在运行过程中发生故障,有些事务尚未完成被迫中断,这些未完成的事务对数据库所做的修改有一部分已写入物理数据库,这时数据库就处于一种不正确的状态,或者说是不一致的状态。

    一致性的概念我不太理解,感觉说的和原子性和持久性一样的。

    Isolation

    隔离性,事务的隔离性指在并发的环境中,并发的事务是相互隔离的,一个事务的执行不能被其他事务干扰。也就是说,不同的事务并发操纵相同的数据时,每个事务都有各自完整的数据空间,即一个事务内部的操作及使用的数据对其它并发事务是隔离的,并发执行的各个事务之间不能下互相干扰。

    各种事务隔离级别

    1. Read Uncommitted

    读未提交,一个事务可以读取另一个事务中未提交的数据。

    2. Read Committed

    读已提交,只允许读取已经被提交的数据。

    3.Repeated Read

    可重复读取,保证在事务处理的过程中,多次读取都是同一个数据。

    4.Serializable

    串行化,所有事务串行执行,即事务只能一个接一个进行处理,不能并发执行。

    持久性

    持久性,事务提交后,不会丢失数据。如电源故障,系统崩溃。

    MySql 数据库事务隔离级别

    mysql版本

    mysql> select version();
    +------------+
    | version()  |
    +------------+
    | 5.7.24-log |
    +------------+
    1 row in set (0.00 sec)
    

    mysql 默认事务隔离级别是

    mysql> show variables like '%isolation%';
    +-----------------------+-----------------+
    | Variable_name         | Value           |
    +-----------------------+-----------------+
    | transaction_isolation | REPEATABLE-READ |
    | tx_isolation          | REPEATABLE-READ |
    +-----------------------+-----------------+
    2 rows in set (0.08 sec)
    

    表结构,当前表数据为空

    mysql> show create table student;
    +---------+-------------------------------------------------------------------------------------------------------------------------------------------------+
    | Table   | Create Table                                                                                                                                    |
    +---------+-------------------------------------------------------------------------------------------------------------------------------------------------+
    | student | CREATE TABLE `student` (
      `id` int(11) NOT NULL,
      `name` varchar(255) DEFAULT NULL,
      PRIMARY KEY (`id`)
    ) ENGINE=InnoDB DEFAULT CHARSET=utf8 |
    +---------+-------------------------------------------------------------------------------------------------------------------------------------------------+
    1 row in set (0.05 sec)
    

    模拟不同隔离级别的场景

    clientA

    start transaction;
    insert into student values (1,'zengting');
    

    1. Read Uncommitted

    clientB

    mysql> set session transaction isolation level read uncommitted;
    Query OK, 0 rows affected (0.00 sec)
    
    mysql> show variables like '%isolation%' ;
    +-----------------------+------------------+
    | Variable_name         | Value            |
    +-----------------------+------------------+
    | transaction_isolation | READ-UNCOMMITTED |
    | tx_isolation          | READ-UNCOMMITTED |
    +-----------------------+------------------+
    2 rows in set (0.00 sec)
    mysql> select * from student;
    +----+----------+
    | id | name     |
    +----+----------+
    |  1 | zengting |
    +----+----------+
    
    

    此时clientB查到1条clientA事务未提交的数据。

    2. Read Committed

    ClientB

    mysql> set session transaction isolation level read committed;
    mysql> select * from student;
    Empty set (0.00 sec)
    

    此时clientB查询不到clientA未提交的数据。

    3.Repeated Read

    clientB

    mysql> set session transaction isolation level repeatable read;
    Query OK, 0 rows affected (0.00 sec)
    
    mysql> show variables like '%isolation%' ;
    +-----------------------+-----------------+
    | Variable_name         | Value           |
    +-----------------------+-----------------+
    | transaction_isolation | REPEATABLE-READ |
    | tx_isolation          | REPEATABLE-READ |
    +-----------------------+-----------------+
    2 rows in set (0.00 sec)
    
    // 注意一定要在事务里查询,不然第二次查询会查询到ClientA提交的数据。
    mysql> start transaction;
    Query OK, 0 rows affected (0.00 sec)
    
    // 第一次查询
    mysql> select * from t_student;
    Empty set (0.01 sec)
    
    // 第二次查询
    // 在此之前将clientA 的事务提交
    mysql> select * from t_student;
    Empty set (0.00 sec)
    
    mysql> commit;
    Query OK, 0 rows affected (0.00 sec)
    
    // 第三次查询
    mysql> select * from student;
    +----+----------+
    | id | name     |
    +----+----------+
    |  1 | zengting |
    +----+----------+
    

    clientB在事务中,不能查到clientA事务提交的结果。多次查询都一样,这就是可重复读。
    clientB事务提交后,又能重新看到clientA提交的数据了。

    4.Serializable

    clientB

    mysql> set session transaction isolation level serializable;
    Query OK, 0 rows affected (0.00 sec)
    
    mysql> start transaction;
    Query OK, 0 rows affected (0.00 sec)
    
    mysql> select * from student;  
    
    // 卡住,在clientA commit后才查询出数据
    
    mysql> select * from student;
    +----+----------+
    | id | name     |
    +----+----------+
    |  1 | zengting |
    +----+----------+
    

    clientB 在事务中查询时刚好有clientA在事务在处理数据,clientB阻塞等待clientA事务提交。

    相关文章

      网友评论

          本文标题:数据库事务

          本文链接:https://www.haomeiwen.com/subject/vkstzltx.html