栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

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

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

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

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 Read 或 Serializable 的时候,不可重复读情况消失,具体情况如下图所示:
3. 幻读

概念:事务执行中,有其他事务增删了某些字段,导致本事务没有得到消息,就感觉像出现幻觉一样。

事务A事务B
开启事务
查询用户JACK的余额 = 500
开启事务
删除用户JACK
提交事务
给JACK用户存200
查询JACK用户余额,欸怎么查不到JACK用户了??

结果:在事务A进行的过程中,B事务对同一张表的其他数据进行了修改没通知A,导致A做了一些无用的幻觉操作。

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

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

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/782226.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号