排他锁共享锁脏读不可重复读幻影行一级封锁协议二级封锁协议三级封锁协议
排他锁排他锁(exclusive locks):指的满足此条件的锁:当某事务对某数据加上排他锁之后,直到该事务释放这个锁之前,其它事务不能再对这个数据再加排他锁和共享锁。 共享锁
共享锁(share locks):指的满足此条件的锁:当某事务对某数据加上共享锁之后,直到所有事务都释放了对该数据加上的共享锁之前,任何事务都不能对该数据加上排他锁,但可以对其加共享锁。
【注意】
排他锁、共享锁本身是无法直接限制事务对数据的读取和修改的。之所以看起来它们能够控制对数据的读取和修改,这需要依赖每个事务在读取和修改数据之前必须要遵守某种约定,这就是:如果要求在某些条件下,某事务需要加某种锁才能对数据进行 *** 作,那么,所有其它事务在遇到同样情况下,也强制必须先加锁才能对数据进行 *** 作,如果加锁加失败,则该事务需要等待。而锁之间是有排斥法则的,所以可以通过这个法则来间接实现对数据读取和修改上的限制。
排他锁对应的要求条件往往是在对数据的修改之前,共享锁对应的则是读取。也就是说,如果对事务启用排他锁,往往意味着,任何事务在修改数据之前都要先加排他锁。如果对事务启用共享锁,往往意味着任何事务在读取数据之前都要先加共享锁。不过,可以自行规定加锁时机。
脏读
脏读(dirty read):如果一个事务在读取数据之前,读到的是某事务在修改后、但提交之前的数据,这称为脏读。
【注意】
如果某事务读取到的数据是历史时期的某个一致性状态下的数据,这不能称之为脏读,这应该叫做旧读。脏读读出来的数据是一个处于中间状态下的数据,这种数据是没有意义的。而旧读出来的数据是一种曾经的正确数据,使用这种数据有可能会导致问题,有可能不会。
不可重复读
不可重复读(nonrepeatable read):在上一次查询之后,如果本事务没有主动变更数据,当本事务再次以相同的条件查询数据时,得到的数据与上一次不一致。(变更指更新、插入、删除,但不包括查找) 幻影行
幻影行(phantom row):对于不同的数据库,可以是以下定义之一。
在上一次查询之后,如果本事务没有主动变更数据,当本事务再次以相同的条件查询数据时,与上一次相比,数据的个数发生了变化。(变更指更新、插入、删除,但不包括查找)
在这个定义中,幻影行属于不可重复读的范畴。
满足以下条件之一即视为出现了幻影行:
某事务连续以相同的条件查询数据时,查询的结果不全相同。(连续指的是查询 *** 作中没有夹杂其它 *** 作)
本次变更数据时,涉及变更前的查询中不存在的数据,但此 *** 作没有引发异常,而是成功变更了该数据。随后本事务再次以相同的条件查询数据时,与上一次查询相比,数据的个数发生了变化。(变更指更新、插入、删除,但不包括查找)
在这个定义中,幻影行不一定属于不可重复读。
【注意】
不可重复读、幻影行描述的都是同一事务的 *** 作。
如果一个事务已经结束,然后又开启新的事务,此时这两个事务分别的查询结果不能用于证明事务是否满足不可重复读、幻影行。
很多情况都会导致事务结束,如事务的提交、回滚、执行 DDL 语句、客户端断开等等。
同一事务要求当前正在观测的事务不能结束,否则该事务结束之后的 *** 作就不能隶属于同一事务。但这仅限于这正在被观测的事务,其它事务是可以任意开启、随时结束,这不影响对同一事务的要求。
一级封锁协议
一级封锁协议:规定:任何事务在修改数据之前,必须先对其加本事务结束才会释放的排他锁,然后在加锁成功之后才能修改数据。
一级封锁协议不能防止脏读、不可重复读。
二级封锁协议
二级封锁协议:规定:任何事务除了要遵守一级封锁协议之外,还应该遵守:在读取数据之前,
如果自己已经对该数据加上了排他锁,则直接读取数据,不再额外加锁。
如果自己此时没有对该数据加上排他锁,则必须先对其加共享锁,然后在加锁成功之后才能读取数据,不过在读取完数据之后就释放共享锁。
二级封锁协议不能防止不可重复读。
三级封锁协议
三级封锁协议:规定:任何事务除了要遵守一级封锁协议之外,还应该遵守:在读取数据之前,
如果自己已经对该数据加上了排他锁或共享锁,则直接读取数据,不再额外加锁。
如果自己此时没有对该数据加上排他锁,则必须先对其加本事务结束才会释放的共享锁,然后在加锁成功之后才能读取数据。
三级封锁协议可以防止脏读、不可重复读,但不能防止旧读。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)