MySQL事务并发与隔离级别

丢失更新:
两个(或以上)事务对同一条数据进行修改,T1、T2同时(并行)开启,但T1执行快,T2执行慢,此时T1提交、T2回滚,造成T1的更新无效。(原因:没有加写锁X、可以对同一条数据进行修改)
注意:这里的丢失更新不是不同事务的覆盖更新问题,覆盖更新应由业务来控制。数据库能做的是保证同一时刻只有一个事务可写某记录,不能保证业务发起的多个事务覆盖更新(事务会排队写)某记录。

脏读:写事务回滚 另一事务读取数据无效
数据库一个读事务T1开启时,允许读取另外一个事务T2未提交的数据,这样这个都事务读取到的数据可能是脏数据。

不可重复读:同一读事务 两次读取同一数据不一致
一个读取事务T1开启时,读取一条行记录,此时另外一个事务T2开启,T2修改了该行记录并提交事务,此时T1事务还没有结束,为了验证数据的有效性,T1再次读取该行记录,两次读取的行记录内容不一致,此现象为不可重复读。

虚读(幻读):一开始有 后来没有 或一开始没有 后来有 像幻觉一样
一个读取事务T1开启时,统计一个表中的数据,此时另外一个事务T2开启,T2向表格中添加或者删除数据并提交,此时T1事务还没有结束,为了验证数据的有效性,T1再次统计表中数据,两次统计结果不一致,此现象为虚读。
 

不可重复读和虚读的区别:
不可重复读是针对一条行记录的update操作,而虚读是针对一个表的insert、delete操作。

锁:
读锁:也叫S锁、共享锁,有锁时允许加其他读锁,不允许加写锁。事务提交后释放。lock in share mode
写锁:也叫X锁、排他锁,有锁时不允许其他任何锁。事务提交后释放。for update
注意:在mysql中,不加锁的任何写,默认加写锁,不加锁的任何读,不会加上读锁(除了隔离级别为可串行化),因此用select语句查询正在被加写锁的数据时,即使写未完成,还是可以查询出结果。

mysql隔离级别:通过锁和快照实现 非单纯使用锁
未提交读:解决丢失更新
给写加上排他锁。同一时刻允许一个事务对同一记录修改。允许未加锁的读,每次写(即使未提交)都刷新数据快照、无锁读前不加快照,因此未加锁的读可以读取未提交的写内容,如果写事务回滚,则造成脏读。
已提交读:解决丢失更新、脏读
给写加上排他锁。同一时刻允许一个事务对同一记录修改。允许未加锁的读,每次写后才刷新数据快照、无锁读前不加快照,因此未加锁的读只能获取提交后的数据,如果写事务回滚,也只能读取上一次提交的数据,因此没有脏读。
可重复读:解决丢失更新、脏读、不可重复读(mysql幻读,通过间隙锁机制)
给写加上排他锁。同一时刻允许一个事务对同一记录修改。允许未加锁的读,每次写后才刷新数据快照、无锁读前加快照(复制最新快照),因此未加锁的读读取无锁读前加的快照,则在同一个读事务中无论其他写事务有没有提交或回滚,每次读到的同一记录都相同,因此可以重复读。
可串行化:解决丢失更新、脏读、不可重复读、幻读
给写加上排他锁。同一时刻允许一个事务对同一记录修改。给读加上共享锁,不允许未加锁的读。读写分离,因此不存在幻读。

mysql的可重复读和可串行化解决幻读区别:
1、可重复读解决幻读,通过间隙锁实现。如果另外一个事务对记录行进行添加或删除操作,在该读事务中依然不变,解决幻读,但在实际记录中,记录行已经插入或已经不存在了。
2、可串行化解决幻读,通过对读加共享锁实现。如果事务T1读取某些记录行,则这些记录行被加共享锁,其他事务T2等,不能对该记录行进行写操作,解决幻读,在实际记录中,在读事务未提交前,这些记录行不允许改变。

无外键关系表中解决幻读:
事务隔离等级应为最高,且添加数据前(用到其他表的主键),应先查询这些主键是否存在(模拟外键关系),查询时这些主键记录被共享锁锁定,不允许删除。如果使用可重复读隔离等级,即使查询这些主键是否存在,也有可能在查询完成后,被其他事务删除该主键记录行(因为没有共享锁保护),当执行完本业务时,该主键记录早已不在。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值