什么是悲观锁(悲观并发控制PCC)与乐观锁?

2024年6月25日08:17:29什么是悲观锁(悲观并发控制PCC)与乐观锁?已关闭评论

锁是保证数据库数据一致性的基石。总的来看,锁分为悲观锁(Pessimistic Lock)和乐观锁(Optimistic Lock)两种形式。悲观锁实际上使用的是“先取锁再访问”的保守策略,为数据处理的安全提供了保证。乐观锁并不会使用数据库提供的锁机制。一般,实现乐观锁的方式就是记录数据版本。锁分类详情如图3-3所示,图中基本涵盖了主流数据库里面涉及的锁类型。

什么是悲观锁(悲观并发控制PCC)与乐观锁?

图3-3 锁分类详情

(1)悲观锁

悲观锁(又名“悲观并发控制”,Pessimistic Concurrency Control,缩写为“PCC”)是一种并发控制的方法。它可以阻止一个事务以影响其他用户的方式来修改数据。

悲观锁主要用于数据争用激烈的环境,以及发生并发冲突时使用锁保护数据的成本要低于回滚事务的成本的环境中。按照不同的分类方式,可以将悲观锁分为多种类型。

1)按性质来分,可将悲观锁分为共享锁、排他锁以及更新锁。

共享(S)锁允许并发事务读取一个资源。资源上存在共享锁时,任何其他事务都不能修改数据。一旦已经读取数据,则立即释放资源上的共享锁,除非将事务隔离级别设置为可重复读或更高级别,或者在事务生存周期内用锁定提示保留共享锁。

排他(X)锁可以防止并发事务对资源进行访问,其他事务不能读取或修改排他锁锁定的数据。

更新(U)锁用于可更新的资源中,防止当多个会话在读取、锁定以及随后可能进行的资源更新时发生常见形式的死锁。从共享锁到排他锁的转换必须等待一段时间,这是因为一个事务的排他锁与其他事务的共享锁不兼容,发生锁等待。当第二个事务试图获取排他锁以进行更新时,由于两个事务都要转换为排他锁,并且每个事务都需要等待另一个事务释放共享锁,因此发生死锁。

2)按作用域来分,可将悲观锁分为行锁、表锁以及页锁。

行锁仅对指定的记录进行加锁,这样其他进程还是可以对同一个表中的其他记录进行操作。行锁开销大,加锁慢;会出现死锁;锁定粒度最小,发生锁冲突的概率最低,并发度也最高。

表锁对整张表加锁,在锁定期间,其他进程无法对该表进行写操作;如果你是写锁,则其他进程也不允许进行读操作;表锁开销小,加锁快;不会出现死锁;锁定粒度大,发生锁冲突的概率最高,并发度最低。

页锁介于行锁以及表锁之间,一次锁定相邻的一组记录。页锁的开销和加锁时间界于表锁和行锁之间;会出现死锁;锁定粒度界于表锁和行锁之间,并发度一般。

3)按锁的行为来分,可将悲观锁分为读锁、意向锁以及写锁。

读锁,即共享锁(S锁),若事务T对数据对象A加上S锁,则事务T可以读A但不能修改A,其他事务只能再对A加S锁,而不能加X锁,直到T释放A上的S 锁。这保证了其他事务可以读A,但在T释放A上的S锁之前不能对A做任何修改。

意向锁解决表锁与之前可能存在的行锁冲突,避免为了判断表是否存在行锁而去扫描全表的系统消耗。

写锁又称排他锁(X锁)。若事务T对数据对象A加上X锁,则事务T可以读A也可以修改A,其他事务不能再对A加任何锁,直到T释放A上的锁。这保证了其他事务在T释放A上的锁之前不能再读取和修改A。

(2)乐观锁

乐观锁假设数据一般情况下不会造成冲突,所以只会在数据进行更新的时候,正式对数据冲突与否进行检测,如果数据冲突了,则返回用户错误的信息,让用户决定如何处理。

  • 版权声明:本篇文章(包括图片)来自网络,由程序自动采集,著作权(版权)归原作者所有,如有侵权联系我们删除,联系方式(QQ:452038415)。