• 常见问题:MySQL/事务隔离


    数据库并行产生的问题

    1. A事务撤销时,将B事务更改的数据撤销。
    2. A事务提交时,将B事务更改的同行数据覆盖。
    3. 脏读:A事务读取到了B事务未提交的数据。
    4. 不可重复读:A事务中同查询语句不幂等,读到已更新数据。
    5. 幻读:A事物中同查询语句不幂等,读到新插入数据。

    数据库事务隔离级别

    1. 串行化(Serializable):一个事务执行过程中完全看不到其他事务,但如果其他事务在操作,只能停等;可避免以上五个问题。
    2. 可重复读(Repeated Read, RR):一个事务可以看到其他事务已提交的新插入记录,但不能看到其他事务对已有行的更新记录;允许幻读。
    3. 读已提交数据(Read Committed, RC):一个事务可以看到其他事务已提交的记录,包括插入和更新;允许幻读和不可重复读。
    4. 读未提交(Read Uncommited):一个事务可以看到其他事务未提交的数据;仅能避免A事务撤销影响B事务。

    InnoDB中的事务实现

    MySQL的引擎是innoDB时,使用的默认隔离级别为,可重复读(RR级);大部分数据库使用的默认隔离级别为读已提交(RC级)。

    实现RC级的事务时,仅需要采用行锁。InnoDB的行锁采用乐观锁的形式实现事务,InnoDB在每行数据后加入两个字段:创建版本号,删除版本号,在事务为默认的RR级以及RC级时,InnoDB事务隔离实现如下:

    • select 读取版本号<=当前事务版本号,删除版本号为空或大于当前事务版本号。
    • insert 保存当前事务版本号为行的创建版本号。
    • delete 保存档前事务版本号为行的删除版本号。
    • update 插入一条新的记录,保存当前事务版本号为行的创建版本号,同时保存当前事务版本号到原来的行。

    需要注意的是,基于上述原理,mysql事务级别为可重复读时,select操作的结果不会有幻读记录,实际上,这是因为mysql的select是一种“快照读”,而非“当前读”。因此,事务为RR级和RC级时,mysql的select是不需要加锁的,但一旦涉及到insert/update/delete,则需要当前读,就需要加锁。

    MySQL事务使用了Next-Key锁,Next-Key锁是行锁和间隙锁的合并。行锁负责给操作行加锁,在RC级中,使用行锁已经足够。而间隙锁,则基于数据作为索引结构的B+树,将数据所在块的邻接块一同加锁,因此可能会锁住不必要的区间,如果不使用索引,则会给全表加锁。

    需要注意的是级别是串行的话,即便是select操作也是加锁的。

    参考文献

    Innodb中的事务隔离级别和锁的关系
    数据库事务隔离级别

  • 相关阅读:
    通过w3c方式 读取xml内容
    ssm项目 maven 项目pon.xml 配置
    myeclipse 2014新建maven web 项目步骤
    Maven学习
    常用正则学习
    Maven 那点事儿
    Chrome 里的请求报错 " Provisional headers are shown"
    php框架thinkphp3.2.3 配置文件bug
    $_GET $_POST $_REQUEST
    php检测函数
  • 原文地址:https://www.cnblogs.com/cielosun/p/11502539.html
Copyright © 2020-2023  润新知