美文网首页
Mysql 事务

Mysql 事务

作者: Ethan_zyc | 来源:发表于2021-07-26 17:48 被阅读0次

    事务的ACID

    • A:atomic 原子性
    • C:consistency 一致性
    • I:Isolation 隔离性
    • D:Durability 持久性

    事务隔离级别

    读未提交

    image

    读已提交

    同一个事务中读到读两次结果不一样,所以也叫不可重复读


    image

    可重复读

    事务A永远读到的是事务刚开始时候的数据


    image

    串行化

    image

    串行化会对表或者表中的目标行加锁,具体实现根据存储引擎来定
    Innodb中的事务隔离级别和锁的关系

    补充:幻读

    这不是隔离级别,只是一个会出现的问题,串行化可以解决幻读


    image

    Mysql 怎么保证可重复读

    回顾一下刚刚的图,明明事务B已经修改了name,那么事务A读的时候李四这个数据是存储在哪边的?

    这就引发出MVCC机制,就是多版本并发控制 multi-version concurrency control

    innodb存储引擎,会在每行数据的最后加两个隐藏列,一个保存行的创建时间,一个保存行的删除时间,但是这儿存放的不是时间,而是事务id,事务id是mysql自己维护的自增的,全局唯一。

    把上图的过程用来举个例子:
    事务A的事务id为1
    事务B的事务id为2

    step1

    查询id=1,得到name=李四

    id name 创建时间 删除时间创建事务id <= 当前事务id,当前事务id < 删除事务id
    1 李四 1 null

    step2

    将id=1的name改成张三,事务还未提交

    id name 创建时间 删除时间
    1 李四 1 null
    1 张三 2 null

    step3

    事务id=1的事务,查询id=1的这一行的时候,一定会找到创建事务id <= 当前事务id的那一行,select * from table where id=1,就可以查到李四的那一行

    补充 step4

    假如事务C(事务id=3)这时候删除了李四,那么删除时间就是3

    id name 创建时间 删除时间
    1 李四 1 3
    1 张三 2 null

    事务A查询id=1还是能查到name=4,因为查询的是

    • 创建事务id <= 当前事务id
    • 删除事务id > 当前事务id

    事务传播级别

    场景:方法A使用了 @Transactional 注解,方法B也使用了 @Transactional 注解,方法A调用了方法B,这时候就需要考虑事务传播级别。

    PROPAGATION_REQUIRED

    默认传播级别
    B不会单独开事务,直接使用A的事务

    PROPAGATION_SUPPORTS

    如果B使用了该传播级别,假如A加了 @Transactional 注解,那么B使用A的事务,如果A没有加 @Transactional 注解,那么B自己也不开事务

    PROPAGATION_MANDATORY

    必须被开启了事务的方法调用,不然就报错

    PROPAGATION_REQUIRES_NEW

    强制自己开一个新的事务,假如事务B使用该隔离级别,如果A调用B的地方try catch了,那么A方法就不会回滚,B会回滚

    PROPAGATION_NOT_SUPPORTED

    使用了该隔离级别的方法不会加入到事务中,报错也不会回滚

    PROPAGATION_NEVER

    不能会开启了事务的方法调用

    PROPAGATION_NESTED

    开启子事务,B会回滚到开启子事务的save point

    相关文章

      网友评论

          本文标题:Mysql 事务

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