一文教你搞懂MySql数据库隔离级别

177 阅读3分钟

这是我参与11月更文挑战的第8天,活动详情查看:2021最后一次更文挑战

演示环境

数据库及工具

  • MySQL版本 8.0.26
  • 数据库工具  Navicat for MySQL

数据库命令

  • 查看数据库版本:select version();

  • 查看数据库现在的隔离级别: select @@transaction_isolation ; 

  • 修改隔离级别 : set session transaction isolation level + 级别参数 ;

  • 级别参数 : READ-UNCOMMITTED , READ -COMMITED , REPEATABLE - READ (MySQL innoDB的默认隔离级别), SERIALIZABLE ; 

  • 开启事务 : start transaction ;

  • 提交 / 回滚 :commit/rollback ;

实际操作

  • 设置数据库级别读未提交  set session transaction isolation level read uncommitted ;

操作一   脏读

A 操作id = 1 的账户余额减去 500 元。

B 去查id = 1的余额 ,显示余额500 元 。

A回滚撤销 ,此时A 余额是1000 。

B的余额增加100。  

结论 :B的余额是600 。真实金额应该是 1100 。原因是读未提交产生了脏读。 

操作二    可重复读

A查询余额600元

B 操作增加400元,余额变成1000元。

A再去查余额变成1000 。

结论 : 两次余额查询不一致 ,可重复读。

操作三 幻读

A查询所有账户的总金额 

B 新增一个用户 和余额 1000 然后提交

A再去查账户的总金额变成了4000 。

  • 设置数据库级别-读已提交  set session transaction isolation level read committed ;

操作一 脏读   情况不会出现 。

A 查询id = 1 的用户,余额修改成 800。

B 去查id = 1 的余额 。查询到的结果是 1000 。

B 去查id = 1 的余额 。修改余额增加100 提交,界面一直转。

窗口A提交后 再去查询B 发现余额为 1100。

操作二 可重复读

A查询id = 1 的余额是1100元

B 操作id = 1 的余额 ,变成 1600  ,提交 。

A再去查余额变成1600 。

同一数据在同一事物中两次余额查询不一致 ,可重复读。

操作三 幻读

A查询所有账户的总金额 是  4800 

B 新增一个用户 和余额 1000 然后提交

A再去查账户的总金额变成了5800 。

幻读仍然存在。

  • 设置数据库级别-可重复读 

操作一 脏读 情况不会出现 。

A 查询id = 1 的用户,修改成 1000。 不提交 演示 ,提交演示。

B 去查id = 1 的余额 。查询到的结果是 1600 。

操作二 可重复读 不会出现

A 查询 余额。1000

B查询id = 1 的余额修改增加 500 元

A 查询 余额。1000

操作三 幻读

A查询所有账户的总金额 是 7200

B 新增一个用户 和余额 1000 然后提交

A再去查账户的总金额变成了7200。

幻读不存在了 ,MYSQL 已经通过锁机制在默认隔离级别的时候,就避免了幻读的出现!