zoukankan      html  css  js  c++  java
  • MySql MVCC是如何实现的-事务隔离级别?

    事务就是要保证一组数据库操作,要么全部成功,要么全部失败。
    在MySql中,事务支持是在引擎层实现的,但是只有InnoDB支持事务,MyISAM是不支持的。
    事务具有原子性,一致性,隔离性,持久性,这里我们要谈的就是隔离性。
    MySql标准的事务隔离级别包括:
    读未提交(read uncomminted):一个事务还没有提交时,它做的变更就能被被的事务看到。
    读提交(read commited):一个事务提交后,它做的变更才会被其他事务看到。
    可重复读(repeatable read):一个事务执行过程中看到的数据,总是跟这个事务在启动时看到的数据是一致的。
    串行化(serializable):对于同一行记录,“写”会加“写锁”,“读”会加“读锁”,出现读写锁冲突的时候,后访问的食物必须等待前一个事务执行完成,才能继续执行。

    事务隔离级别 脏读 不可重复读 幻读
    读未提交
    不可重复读
    可重复读
    串行化

    1.查看MySql默认的隔离级别,可见MySql默认可重复读。从上图我们可以看到,不管是什么隔离级别,都会存在一些问题,并且隔离的越严实,执行效率就会越低。比如:串行化,所以很多时候我们只是在效率和隔离之间找一个平衡点。

    MySql5.7以前的版本:show variables like 'tx_isolation';
    MySql5.7(包含)以后的版本:show variables like 'transaction_isolation';

    mysql> show variables like 'tx_isolation';
    +---------------+-----------------+
    | Variable_name | Value |
    +---------------+-----------------+
    | tx_isolation | REPEATABLE-READ |
    +---------------+-----------------+
    1 row in set (0.00 sec)

    举例说明:

    事务A 事务B
    1启动事务
    2.查询得到值V0 3启动事务
    4.查询得到值V0
    5.将V0改为V0+1
    6.查询得到值V1
    7.提交事务B
    8.查询得到值V2
    9.提交事务A
    10.查询得到值V3

    1.读未提交

    • 将会话的隔离级别设置为读未提交,终端1和终端2一起设置
    set session transaction isolation level read uncommitted;
    
    • 按照上述表格中的顺序,依次执行,得到V0=1,V1=2,V2=2,V3=2

    注意步骤6直接读到了步骤5中修改的值,此时事务B实际还未提交,这就是读未提交(read uncommited),事务级别读未提交存在脏读的问题,比如此用例中如果事务B做了回滚,那么事务A在第4步骤查询得到的值就是不正确的,这就是所谓的脏读

    2.读提交

    • 将会话的隔离级别设置为读提交,终端1和终端2一起设置
    set session transaction isolation level read committed;
    
    • 按照上述表格中的顺序,依次执行,得到V0=2,V1=2,V2=3,V3=3

    注意步骤6没有读到步骤5中修改的值,步骤7,事务B提交之后,步骤8读到了步骤5修改的值,这就是读提交(read commited),事务级别读提交存在不可重复读的问题,比如此用例中,同一个事务,在不同的阶段读同一行数据读到了不同的值,这就是所谓的不可重复读,解决不可重复读的方法是加行锁,事务A在执行未提交的时候,事务B无法修改数据,即可避免

    3.可重复读

    • 将会话的隔离级别设置为可重复读,终端1和终端2一起设置
    set session transaction isolation level repeatable read;
    
    • 按照上述表格中的顺序,依次执行,得到V0=3,V1=3,V2=3,V3=4

    注意步骤6没有读到步骤5中更改的值,步骤7事务B提交之后,步骤8依然没有读到步骤5中更改的值,直到事务A也提交之后才读到事务B更改的值,这就是可重复读(repeatable read)

    • 事务级别可重复读存在幻读的问题
    事务A 事务B
    1启动事务
    2查询V0
    3插入
    4查询V1
    5提交事务
    6查询V2
    7更新
    8查询V3
    • 按照上述表格的顺序,依次执行,V0=V1=V2=5行,V3=6行,也就是在事务A中查到事务B插入的数据,这就是所谓的幻读,解决幻读的方法是加表锁,事务A在执行未提交的时候,事务B无法插入数据,即可避免

    4.串行化

    • 将会话的隔离级别设置为串行化,终端1和终端2一起设置
    set session transaction isolation level serializable;
    
    事务A 事务B
    1启动事务
    2启动事务
    3插入数据
    4查询数据
    5提交事务
    6查询数据

    按照上述表格的顺序,依次执行,步骤3插入数据,但是未提交的时候,步骤4出现了获取锁超时的情况,这就是串行化(serializable
    ,同一行数据不允许并发执行,在写时,读必须等待。

    牛人之所以是牛人,是因为你现在在踩的坑,他曾经都已经踩过了。
  • 相关阅读:
    iOS应用程序间共享数据(转)
    解决右滑返回手势和UIScrollView中的手势冲突(转)
    (转)iOS被开发者遗忘在角落的NSException-其实它很强大
    iOS 身份证最后一位是X,输入17位后自动补全X(转)
    springboot单机秒杀之queue队列
    springboot单机秒杀-aop+锁
    springbot单机秒杀,锁与事务之间的大坑
    spring-cloud学习之4.微服务请求打通
    spring-cloud学习之3.使用feign实现负载均衡
    spring-cloud学习之2.搭建请求网关spring-cloud-getway
  • 原文地址:https://www.cnblogs.com/dwBurning/p/mvcctransaction.html
Copyright © 2011-2022 走看看