文章插图
比如事务A第一次读取到值为A,接着事务B修改为B,并且提交了事务B,然后事务A再次读取得到的数据是B,同一行数据多次读取值并不相同,这称作不可重复读 。它是指在同一个事务里面查询同一行数据,每次查到的数据都不一样 。和脏读区别在于脏读是由于别的事务回滚导致,而不可重复读读到的其实是已经提交的数据 。
事务A读到事务B提交后的数据似乎很合理,但是我们想象这样一种场景:你有一个流水表和用户余额,其中记录用户每天的流水,你在月初0点的时候核对流水和库存,但是流水很多,你的程序选择一个一个用户的进行核对,核对用户甲,甲没做任何消费,但是当你核对B的时候,你将B的流水load到内存中,但是B这时候(0点30分,这一笔数据新的一个余额)进行了扣除余额的操作,导致B余额和流水对不上了 。
4.幻读如果一个事务A先根据没用搜索条件查询到一些记录,在该事务未提交前,另外一个事务写入(delete,update,insert)了符合搜索条件的记录,这时候事务A再次读取,发现数据条数和第一次读取的不同,如同出现了幻觉,称之为幻读

文章插图
事务A读到事务B提交后的数据似乎很合理,但是我们想象这样一种场景:你有一个需求将会公司的男性员工了女性员工查询进行展示,你先查询了总数为100人,然后查询男性的总数50人,后查询女性人数准备在页面展示共100人,其中男50人,女50人,结果这是管理信息的人发现有一位员工性别错误录入了,将其从男修改为女,这时候你读取事务就是女51人了,你在主页显示了共100人,其中男50人,女51人
三丶隔离级别1.Read UnCommitted 读未提交在此隔离级别下,会发生脏读,不可重复读,和幻读
2.Read Committed 读已提交在此隔离级别下,会发生不可重复读,和幻读
3.Repeatable Read 可重复读在此隔离级别下,可能发生幻读
4.Serializable 可串行化在此隔离级别下,不会发生脏读,不可重复读,和幻读
其中脏写是对一致性影响最严重的,无论是何种隔离级别,都不允许脏写发生,innodb使用锁保证不会出现脏写现象,第一个事务更新某条记录的时候,会给这条记录加锁,另外一个事务在此更新的时候,需要等待第一个事务提交释放锁后更新 。隔离级别越高,其并发能力越低 。
四丶Mysql设置隔离级别默认隔离级别可重复读
1.设置全局隔离级别SET GLOBAL TRANSACTION ISOLATION LEVEL 期望的隔离级别(可选READ UNCOMMITED,READ COMMITED,REPEATABLE READ,SERIALIZABLE),此命令只对执行语句后新产生的会话有效,对当前已经存在的会话无效
2.设置会话隔离级别SET SESSION TRANSACTION ISOLATION LEVEL 期望的隔离级别(可选READ UNCOMMITED,READ COMMITED,REPEATABLE READ,SERIALIZABLE),对当前会话后续事务有效,该语句可以在已开启的事务中执行,但是不会影响当前正在执行的事务,如果在事务之间执行,只会对后续的事务有效
3.设置下一个事务的隔离级别SET TRANSACTION ISOLATION LEVEL 期望的隔离级别(可选READ UNCOMMITED,READ COMMITED,REPEATABLE READ,SERIALIZABLE) 只对当前会话的下一个即将开启的事务有效,下一个事务执行完后,后续事务将恢复到之前的隔离级别,该语句不能再已经开启的事务中执行,否则会报错 。
4.指定服务器的隔离级别在启动的时候使用--transaction-isolation=xxx即可执行默认隔离级别
五丶MVCC原理下面讨论记录对当前事务是否可见都是基于当前事务中执行的查询是快照读(普通查询),对于当前读(select xxx for update,select xxx lock in share mode)是不通用的
经验总结扩展阅读
- C#多线程之线程基础篇
- 豆腐在冷藏室可以放几天
- 200ml牛奶是多少克
- 一碗米饭的热量是多少
- 45岁男士体脂率多少正常 45岁男人体脂率多少
- 70多岁还能骑自行车吗 70岁老人能骑自行车吗
- 虾干热量有多少 虾干的热量是多少
- 一个水煮蛋多少大卡
- 板栗放冰箱里能存放多久
- 螃蟹干放着能活多久