1.丢失更新 :
两个不同事物同时获得相同数据,然后在各自事务中同时修改了该数据,那么先提交的事务更新会被后提交事务的
更新给覆盖掉,这种情况事务A的更新就被覆盖掉了、丢失了。
2.脏读(未提交读)
事务读取了未提交的数据,事务B的回滚,导致了事务A的数据不一致,导致了事务A的脏读 !
3.不可重复读
一个事务在自己没有更新数据库数据的情况,同一个查询 *** 作执行两次或多次的结果应该是一致的;如果不一致,就说明为不可重复读。
4.幻读(Phantom Read)
事务A读的时候读出了15条记录,事务B在事务A执行的过程中 增加 了1条,事务A再读的时候就变成了 16 条,这 种情况就叫做幻影读。 不可重复读说明了做数据库读 *** 作的时候可能会出现的问题。
一级封锁协议 (对应 read uncommited)
一级封锁协议是:事务 在对需要修改的数据上面(就是在发生修改的瞬间) 对其加共享锁(其他事务不能更改,
但是可以读取-导致“脏读”),直到事务结束才释放。事务结束包括正常结束(COMMIT)和非正常结束。
一级封锁协议不能避免 丢失更新,脏读,不可重复读,幻读!
二级封锁协议 (对应read commited)
二级封锁协议是:
1)事务 在对需要更新的数据 上(就是发生更新的瞬间) 加 排他锁 (直到事务结束),防止其他事务读取未提交
的数据,这样,也就避免了 “脏读” 的情况。
2)事务 对当前被读取的数据 上面加共享锁(当读到时加上共享锁),一旦读完该行,立即 释放该该行的共享锁 -
上面只能防止不读脏数据
二级封锁协议除防止了“脏读”数据,但是不能避免 丢失更新,不可重复读,幻读 。
如果要避免 丢失更新,我们需要额外的 *** 作, 对凡是读到的数据加 共享锁 和排他锁 ,这个往往需要程序员自己
编程实现,比如在Oracle 中,需要加 SELECT FOR UPDATE 语句,表明,凡是该事务读到的数据,额外的加上排
他锁,防止其他数据同一时间获取相同数据,这样就防止了 丢失更新 !
三级封锁协议 (对应reapetable read )
三级封锁协议除防止了“脏”数据 和不可重复读 。但是这种情况不能避免 幻读 和 丢失更新 的情况,在事务 A 没有 完成之前,事务 B 可以新增数据,那么 当事务 A 再次读取的时候,事务B 新增的数据会被读取到,这样,在该封 锁协议下,幻读 就产生了。
( 如果要避免 丢失更新,我们需要额外的 *** 作, 对凡是读到的数据加 共享锁 和排他锁 ,这个
往往需要程序员自己编程实现,比如在Oracle中,需要加 SELECT FOR UPDATE 语句,表明,凡是读到的数据,我 会加 排他锁,防止其他数据同一时间获取相同数据) !
最强封锁协议(对应Serialization)
四级封锁协议是对三级封锁协议的增强,其实现机制也最为简单,直接对 事务中 所 读取 或者 更改的数据所在的
表加表锁,也就是说,其他事务不能 读写 该表中的任何数据。这样所有的 脏读,不可重复读,幻读 ,都得以避 免!
MVCC(多版本并发控制)
mysql的innodb采用的是行锁,而且采用了多版本并发控制来提高读 *** 作的性能
MVCC只在REPEATABLE READ和READ COMMITED两个隔离级别下工作,其它两个隔离级别下不存在MVCC
什么是多版本并发控制呢 ?其实就是在每一行记录的后面增加两个隐藏列,记录创建版本号和删除版本号, 而每一个事务在启动的时候,都有一个唯一的递增的版本号。通过版本号来减少锁的争用。 另外,只有read-committed和 repeatable-read 两种事务隔离级别才能使用mVcc
read-uncommited由于是读到未提交的,所以不存在版本的问题 ,而serializable 则会对所有读取的行加锁。
间隙锁(Next-Key锁)
当我们用范围条件而不是相等条件检索数据,并请求共享或排他锁时,InnoDB会给符合条件的已有数据记录的索 引项加锁;对于键值在条件范围内但并不存在的记录,叫做“间隙(GAP)”,InnoDB也会对这个“间隙”加锁,这种锁 机制就是所谓的间隙锁(Next-Key锁)。
欢迎关注公众号:北漂之路之程序人生(技术博客)
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)