美文网首页
select+update引发的一些思考(4)真相大白

select+update引发的一些思考(4)真相大白

作者: lqsss | 来源:发表于2018-02-22 23:21 被阅读0次

捋捋思路,本章是一个总结,回答下前面的问题!

A:

Q1. UPDATE的行锁问题?

update操作时自带了行锁(写锁),只不过锁释放的时机会影响到并发事务时,是否发生的一系列问题(脏读、不可重复读、更新覆盖)

Q2. commit之前有所误解,事务提交和数据写入有所弄混(redo、undo、写入磁盘等)

  1. commit与修改数据持久化没关系,事务提交之前,有可能数据持久化到磁盘里;事务提交之后,数据也没有马上持久化到磁盘;
  2. wal:日志比数据先进行持久化操作。出现故障后,通过日志是否完全持久化(结束标志)判断是否进行数据的提交恢复(redo),还是根据undo日志进行回滚。

Q3. 由上述问题引发事务隔离与锁的问题

这里上述问题(脏读、不可重复读、更新覆盖)。

  1. RU(最低级,全都无法避免,一级封锁)
  2. RC(避免脏读,二级封锁) 事务更新数据上排他锁(事务结束才释放),共享锁读一下就释放(不可重复读)
  3. RR(无法避免幻读,三级封锁)读的时候上共享锁(直到事务结束才释放),三级封锁实现二阶段锁定(ACID)
  4. Serialization(事务串行化,最高级)解决了幻读,直接对 事务中 所 读取 或者 更改的数据所在的表加表锁(“范围锁”)

Q4. 二阶段锁定和那些事务执行中的锁 概念有所弄混

二阶段锁保证并发调度,实现事务的隔离性(事务开始获取锁,事务结束释放锁);如果事务都完完全全实现隔离性,没有并发,效率太低,所有就有了事务隔离等级,事务执行的锁(共享锁、排他锁)。
例如之前的RC级别,更新操作的时候上排他锁(直到事务结束释放),并不是事务一开始就获得(不满足二阶段锁定),造成了不可重复读、更新覆盖、幻读问题。
例如用SELECT FOR UPDATE(悲观锁,在查询的时候就上排他锁,防止其他事务获得该数据)解决更新覆盖。
三级封锁协议必定满足二阶段锁定

ps:二阶段锁定保证隔离性,二进制日志保证原子性

其他

三级封锁协议的死锁问题

进阶:repeatable read 导致死锁的情况(即便是 不同的资源在相同的顺序下获取)。 比如 事务1 读取 A,同时 事务2 也读取 A,那么事务1和事务2 同时对 A 上了共享锁,然后事务1 要UPDATE A,而此时 事务2 也要 UPDATE A,这个时候 事务1 等待 事务2 释放其在 A 上的共享锁,然后 事务2 要等待 事务1 释放其在 A 上的共享锁,这样,事务1 和 事务2 相互等待,产生死锁!(SQL Server/DB2 里面有 UPDATE LOCK 可以解决这种情况,具体的思路是,在 repeatable read 的情况下,将读取的数据 上的 UPDATE 锁,介于 共享锁 和 排他锁之间的一种锁,该锁的作用是 当出现上面这种情况后,事务1 和 事务2 对 A 上的是 UPDATE 锁,那么谁先 要修改 A,那么该事务就会将 UPDATE 锁可以顺利升级为 排他锁对该数据进行修改!)

参考

共享锁
数据库事务隔离级别与锁机制实现(转载)
浅析数据库事务的隔离性(isolation)

相关文章

网友评论

      本文标题:select+update引发的一些思考(4)真相大白

      本文链接:https://www.haomeiwen.com/subject/ydjztftx.html