MySQL 事务

时间秒杀一切 提交于 2020-01-28 16:05:34

银行引用是事务的一个经典例子:假如银行有两张表,一张支票表,一张储蓄表,现在需要从Jones用户的支票账户转移200¥ 至储蓄账户,那么至少需要三步:
    1. 检查Jones的支票账户余额是否大于200¥
    2. Jones的支票账户-200¥
    3. Jones的储蓄账户+200¥
上述三步可组成一个事务,当2、3步故障时,之前执行的操作会自动回滚,保证数据的一致性。

    

一、MySQL事务

MySQL事务是一组SQL语句或一个独立运行的工作单元并且满足ACID测试。
    
 
ACID测试:
    A.atomicity,原子性,一个事务必须作为不可分割的最小单元,事务中的语句要么都执行成功,要么都执行失败。
    C.consistency,一致性,数据库总是从一个一致性状态到另一个一致性状态(数据库的结果是一致的,所有事务中SQL语句共同修改后的结果)不可能因为系统奔溃出现上述支票表-200¥而储蓄表未+200¥,未提交的事务并不会保存至数据库中。
    I. isolation ,隔离性,当前事务操作过程对于另一个线程事务的可见度,由隔离级别决定。
    D. durability , 持久性 , 所有事务提交后都永久存放于数据库中。
    
    

隔离级别:
    1. READ UNCOMMITTED (读未提交)
    2. READ COMMITTED(读提交)
    3. REPEATEABLE READ(可重复读)
    4. SERIALIZABLE(序列化)
    
各个隔离级别可能产生的问题:

a.脏读,当前线程事务可以读取另一个线程事务未提交修改的数据。
b.不可重复读,事务提交前看到的数据不一致(别的线程修改提交); 线程1开启事务查询数据一个样,当线程2开启事务修改提交后,线程1再次查询发现数据修改(未提交),这就是不可重复读。  
c.幻读, 可重复读级别通过MVCC机制保证事务提交前看到的数据都是一致的,但是又有一个新问题,当线程2修改完数据提交后,线程1看到的还是未修改前的原始数据,但实际底层数据已被更改,当线程1提交后发现数据改变,像幻觉一样,这就是幻读。
d.加锁读,SERIABLIZEBLE 为了解决幻读问题,当线程事务1查询数据,线程事务2修改数据会被锁住,因为数据具有不确定性。

MySQL 事务
事务相关的命令:

START   TRANSACTION       #开启事务
ROLLBACK        #回滚事务
COMMIT             #提交事务
SAVEPOINT identifier          #事务语句过多时,可以创建一个保存点,单独还原至此点
ROLLBACK [WORK] TO [SAVEPOINT] identifier        #还原事务至此点
RELEASE SAVEPOINT identifier                                 #删除保存点

二、验证各事务隔离级别存在的问题:

 
1. READ UNCOMMITTED ——幻读
a.首先需要关闭事务自动提交功能
MySQL 事务
b.修改事务隔离级别为READ-UNCOMMITTED
MySQL 事务
c.开启事务功能
MySQL 事务
d.在一线程事务中修改数据但不提交,在另一线程查看数据已更改,这就是脏读,存在脏读就必然存在不可重复读、幻读问题。
MySQL 事务
2. READ COMMITTED——解决脏读,新问题:不可重复读
a. 修改事务级别为 READ-COMMITTED .
MySQL 事务
b. 开启事务,并在一线程中删除数据,另一线程查看发现数据已更改,这就是不可重复读。
MySQL 事务
MySQL 事务
3. REPEATEABLE READ——解决不可重复读,新问题:幻读
a.修改事务级别为REPEATABLE-READ
MySQL 事务
b.开启事务、并查询数据
MySQL 事务
c.线程2删除数据并提交,线程1事务未提交查看数据发现未改变(可重复读)
MySQL 事务
d.线程1提交事务发现数据已被改变,这就是幻读,事务提交前数据已被改变,但无法察觉到,事务未修改提交后却发现数据改变
MySQL 事务
4. SERIALIZABLE——解决幻读,新问题:加锁读
a.设置隔离级别为SERIALIZABLE,在线程1查看数据,线程2修改数据发现被锁住了,因为无法保证线程1事务提交后看到的数据一致,这就是加锁读
MySQL 事务

注意:需要先关闭autocommit=OFF ,并且需要在线程SELECT查看一次才能做出加锁效果。

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!