MySQL事务、隔离级别与锁

MySQL中的事务四要素

  • 原子性(Atomicity):要么全部完成,要么全部不完成;
  • 一致性(Consistency):事务执行前后都保持数据的完整性约束,数据的中间状态不可见;
  • 隔离性(Isolation):事务之间不能相互影响,可以设置不同的隔离级别;
  • 持久性(Durability):事务提交后会持久到磁盘,事务所作的更新不会丢失。

MySQL事务定义了四种隔离级别

  • 读未提交(Read Uncommitted),本事务可以读取到其它事务未提交的数据更新
  • 读已提交(Read Committed),本事务内只能读取其它事务已经提交的更新
  • 可重复读(Repeatable Read),InnoDb的默认隔离级别,本事务内读取的数据行一定是一致的
  • 序列化(Serializable),最高隔离级别,事务串行化执行。

与隔离级别相关的几个事务并发问题

  • 脏读,RU级别会出现的问题,即A事务读取了B事务修改某个字段后的值
  • 不可重复读,同一个事务先后读取两次同一记录,得到了两个不同的值。与脏读的区别是,脏读是事务读取了其它事务未提交的修改,不可重复读是本事务读取了其它事务已提交的修改。
  • 幻读,本事务在读取某一范围的数据时,其它事务在该范围内添加或删除了记录,导出本事务前后两次读取的数据集不同。
  • 丢失更新,分为两类。第一类丢失更新指事务的回滚覆盖了另一个事务提交的修改。第二类更新是事务提交的修改覆盖了另一个事务的修改。

MySQL的四种隔离级别分别可以解决的并发问题

隔离级别 脏读 不可重复读 幻读 第一类丢失更新 第二类丢失更新
读未提交 可能 可能 可能 可能
读已提交 可能 可能 可能
可重复读 可能
序列化

MySQL如何实现四种隔离级别?

传统的方式是基于锁的事务隔离,读未提交中事务读不加锁,事务写加持续X锁;读已提交中事务读加临时S锁,事务写加持续X锁;可重复读中事务读加持续S锁,事务写加持续X锁;序列化,事务读写都加表级锁。
MySQL采用MVCC(Multi Version Concurrent Control)的方式实现事务隔离,在读未提交级别下,始终读取数据行的最新版本,而序列化级别每次读取都会加上锁。
对于RC和RR级别,情况又有不同。以下面这条sql为例:

select * from table where ?;

RC级别会首先寻找数据行的最新版本,如果数据行被锁,则寻找最新的快照版本。
RR级别则会读取事务开始时的版本。
RR和RC这两种实现都称为快照读(Snapshot Read)。除了快照读外,MySQL还提供了当前读(Current Read),这种方式会读取数据的最新版本,并加锁。根据加锁的类型不同,分为:
SELECT ... LOCK IN SHARE MODE 加S锁
SELECT ... FOR UPDATE 加X锁
INSERT/UPDATE/DELETE 加X锁

posted @   g2012  阅读(112)  评论(0编辑  收藏  举报
编辑推荐:
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
· 没有源码,如何修改代码逻辑?
· 一个奇形怪状的面试题:Bean中的CHM要不要加volatile?
· [.NET]调用本地 Deepseek 模型
· 一个费力不讨好的项目,让我损失了近一半的绩效!
阅读排行:
· PowerShell开发游戏 · 打蜜蜂
· 在鹅厂做java开发是什么体验
· 百万级群聊的设计实践
· WPF到Web的无缝过渡:英雄联盟客户端的OpenSilver迁移实战
· 永远不要相信用户的输入:从 SQL 注入攻防看输入验证的重要性
点击右上角即可分享
微信分享提示