美文网首页
MySQL系列之一 -- 事务

MySQL系列之一 -- 事务

作者: 花神子 | 来源:发表于2020-02-09 11:09 被阅读0次

    如果未做特殊声明,本系列所有文章,均是默认存储引擎InnoDB,隔离级别为RR

    • MySQL的事务,事务的特性
    • 事务传播特性
    • MySQL4中事务的隔离级别,及实现原理

    MySQL的事务

    事务(Transaction) 是作为一个单元的一组有序的数据库操作。如果组中的所有操作都成功,则认为事务成功。
    事务具有4个特性:原子性(Atomicity)、一致性(Consistency)、隔离性(Isolation)和持续性(Durability)。这四个特性也简称ACID性。

    传播特性

    传播特性 该特性是保证事务是否开启,业务逻辑是否使用同一个事务的保证。当事务在传播过程中会受其影响。其传播特性包括:

    1. Propagation.REQUIRED:方法被调用时自动开启事务,在事务范围内使用则使用同一个事务,否则开启新事务。
    2. Propagation.REQUIRES_NEW:无论何时自身都会开启事务
    3. Propagation.SUPPORTS:支持当前事务,如果当前存在事务,就加入该事务,如果当前不存在事务,就以非事务执行。
    4. Propagation.NOT_SUPPORTED:自身不会开启事务,以非事务方式执行操作,如果当前存在事务,就把当前事务挂起,运行完毕恢复事务。
    5. Propagation.MANDATORY:支持当前事务,如果当前存在事务,就加入该事务,如果当前不存在事务,就抛出异常。
    6. Propagation.NEVER:自身不会开启事务,以非事务方式执行,如果当前存在事务,则抛出异常。
    7. Propagation.NESTED:如果一个活动的事务存在,则运行在一个嵌套的事务中. 如果没有活动事务, 则按TransactionDefinition.PROPAGATION_REQUIRED 属性执行。

    另:最常用的设置为:Propagation.REQUIRED

    事务的隔离级别

    按照SQL92标准,InnoDB实现了四种不同事务的隔离级别:

    • 读未提交(Read Uncommitted)
    • 读提交(Read Committed, RC)
    • 可重复读(Repeated Read, RR)
    • 串行化(Serializable)

    四种事务的隔离级别原理

    读未提交(Read Uncommitted)

    SELECT statements are performed in a nonlocking fashion.
    这种事务隔离级别下,select语句不加锁。此时,可能读取到不一致的数据,即“读脏”。这是并发最高,一致性最差的隔离级别。

    读提交(Read Committed, RC)

    这是互联网最常用的隔离级别,在RC下:

    1. 普通读是快照读: 普通的select使用快照读(snapshot read),这是一种不加锁的一致性读(Consistent Nonlocking Read),底层使用MVCC来实现。
    2. 加锁读: 加锁的select, update, delete等语句,除了在外键约束检查(foreign-key constraint checking)以及重复键检查(duplicate-key checking)时会封锁区间,其他时刻都只使用记录锁;
    3. 其他事务的插入依然可以执行,就可能导致,读取到幻影记录。

    可重复读(Repeated Read, RR)

    InnoDB默认的隔离级别,在RR下:

    1. 普通读是快照读: 普通的select使用快照读(snapshot read),这是一种不加锁的一致性读(Consistent Nonlocking Read),底层使用MVCC来实现。
    2. 加锁读: 加锁的select(select ... in share mode / select ... for update), update, delete等语句,它们的锁,依赖于它们是否在唯一索引(unique index)上使用了唯一的查询条件(unique search condition),或者范围查询条件(range-type search condition):
      • 在唯一索引上使用唯一的查询条件,会使用记录锁(record lock),而不会封锁记录之间的间隔,即不会使用间隙锁(gap lock)与临键锁(next-key lock)
      • 范围查询条件,会使用间隙锁与临键锁,锁住索引记录之间的范围,避免范围间插入记录,以避免产生幻影行记录,以及避免不可重复的读。

    串行化(Serializable)

    To force a plain SELECT to block if other transactions have modified the selected rows.
    这种事务的隔离级别下,所有select语句都会被隐式的转化为select ... in share mode.
    这可能导致,如果有未提交的事务正在修改某些行,所有读取这些行的select都会被阻塞住。这是一致性最好的,但并发性最差的隔离级别。在互联网大数据量,高并发量的场景下,几乎不会使用上述隔离级别。

    小结

    • 并发事务之间相互干扰,可能导致事务出现读脏,不可重复度,幻读等问题
    • InnoDB实现了SQL92标准中的四种隔离级别
    • 读未提交:select不加锁,可能出现读脏;
    • 读提交(RC):普通select快照读,锁select /update /delete 会使用记录锁,可能出现不可重复读;
    • 可重复读(RR):普通select快照读,锁select /update /delete 根据查询条件情况,会选择记录锁,或者间隙锁/临键锁,以防止读取到幻影记录;
    • 串行化:select隐式转化为select ... in share mode,会被update与delete互斥;
    • InnoDB默认的隔离级别是RR,用得最多的隔离级别是RC。

    相关文章

      网友评论

          本文标题:MySQL系列之一 -- 事务

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