数据库几个事务相关的知识点(脏读幻读不可重复读以及如何避免)

本文详细解析了MySQL中四种不同的事务隔离级别:读未提交、读已提交、可重复读和序列化。通过具体示例介绍了每种隔离级别下可能发生的脏读、不可重复读及幻读现象,并给出了相应的解决方案。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

0. 设置MYSQL的隔离界别

# 查询数据库当前事务隔离级别
mysql> select @@global.transaction_isolation,@@transaction_isolation;
+--------------------------------+-------------------------+
| @@global.transaction_isolation | @@transaction_isolation |
+--------------------------------+-------------------------+
| REPEATABLE-READ                | REPEATABLE-READ         |
+--------------------------------+-------------------------+
1 row in set (0.00 sec)

# 设置数据库事务隔离级别为 读未提交
set global transaction isolation level READ UNCOMMITTED;

# 这一句话只针对当前客户端生效,因此两个客户端都需要
set session transaction isolation level READ UNCOMMITTED;

# 关闭事务的自动提交
set autocommit = 0;

1. 脏读

  • 脏读概念:读取了其他事务未提交的数据,可能会造成严重的数据错误(理论上来说如果两个事务都正常提交就没问题)
事务A事务B
开启事务开启事务
查询TOM用户的余额 = 100查询JOHN余额 = 1100
JOHN给TOM转500
查询TOM用户的余额 = 600
TOM用户花300买了个耳机
JOHN使用的支付转账设备异常,对支付状态校验失败,于是事务回滚
  • 结果:数据异常,余额只有100 的TOM买了个300的耳机。
  • 脏读其实在MYSQL中一般是不会出现的,即使我们手动将MYSQL的隔离级别调整至最低的读未提交,MyISAM的表不支持事务,InnoDB在事务对某行进行修改的时候会自动加上行锁,相当于TOM买耳机的这个操作会被阻塞等待,因此不用对脏读太过担心。

2. 不可重复读

  • 概念:由于第一次读取和第二次读取同一行记录的时间段中有另一个事务 修改 了数据,导致前后两次读取的结果不一致
事务A事务B
开启事务
查询TOM的余额 = 300
TOM买了300的耳机
开启事务
领导给TOM发了500工资
提交事务
再次查询TOM的余额 = 500,欸我怎么原300买300还剩500
  • 结果:在事务A看来,事务期间对于TOM这一行的数据重复读取的时候获得了不一样的结果,数据异常。
  • 不可重复读可以通过设置数据库的隔离级别来进行规避,当数据库的事务隔离级别为Repeatable ReadSerializable 的时候,不可重复读情况消失,具体情况如下图所示:
    在这里插入图片描述

3. 幻读

  • 概念:事务执行中,有其他事务增删了某些字段,导致本事务没有得到消息,就感觉像出现幻觉一样。
事务A事务B
开启事务
查询用户JACK的余额 = 500
开启事务
删除用户JACK
提交事务
给JACK用户存200
查询JACK用户余额,欸怎么查不到JACK用户了??
  • 结果:在事务A进行的过程中,B事务对同一张表的其他数据进行了修改没通知A,导致A做了一些无用的幻觉操作。

  • MYSQL避免幻读的方式:(摘自【MYSQL如何解决幻读】
    (1) 隔离级别可重复读下,快照读 MVCC + 当前读 Next-Lock Key(只在可重复读隔离级别下生效)
    在这里插入图片描述

(2)隔离级别:SERIALIZABLE,在这个隔离级别下,事务在读操作时,先加表级别的共享锁,直到事务结束才释放;事务在写操作时,先加表级别的排它锁,直到事务结束才释放。也就是说,串行化锁定了整张表,幻读不存在的

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

啪!~

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值