悲观锁和乐观锁

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://xxlcube.blog.csdn.net/article/details/10536117

悲观锁

对数据被修改,非常保守,必须要将事务加锁,所以在悲观锁的情况下,所有事务操作都要加锁,依靠数据库的锁机制来保证数据的一致性。

但是性能开销较大

如一个金融系统,当某个操作员读取用户的数据,并在读出的用户数据的基础上进 
行修改时(如更改用户帐户余额),如果采用悲观锁机制,也就意味着整个操作过 
程中(从操作员读出数据、开始修改直至提交修改结果的全过程,甚至还包括操作 
员中途去煮咖啡的时间),数据库记录始终处于加锁状态,可以想见,如果面对几

百上千个并发,这样的情况将导致怎样的后果。 


乐观锁

在这种情况下,不采用数据库的锁机制,而是通过版本

乐观锁,大多是基于数据版本 
( Version )记录机制实现。何谓数据版本?即为数据增加一个版本标识,在基于 
数据库表的版本解决方案中,一般是通过为数据库表增加一个 “version” 字段来 
实现。 
读取出数据时,将此版本号一同读出,之后更新时,对此版本号加一。此时,将提 
交数据的版本数据与数据库表对应记录的当前版本信息进行比对,如果提交的数据 
版本号大于数据库表当前版本号,则予以更新,否则认为是过期数据。 
对于上面修改用户帐户信息的例子而言,假设数据库中帐户信息表中有一个 
version
 字段,当前值为 1 ;而当前帐户余额字段( balance )为 $100 。 
操作员 此时将其读出( version=1 ),并从其帐户余额中扣除 $50
( $100-$50 )。 
在操作员 A 操作的过程中,操作员 B 也读入此用户信息( version=1 ),并 
从其帐户余额中扣除 $20 ( $100-$20 )。 
操作员 A 完成了修改工作,将数据版本号加一( version=2 ),连同帐户扣 
除后余额( balance=$50 ),提交至数据库更新,此时由于提交数据版本大 
于数据库记录当前版本,数据被更新,数据库记录 version 更新为 2 。 
操作员 B 完成了操作,也将版本号加一( version=2 )试图向数据库提交数 
据( balance=$80 ),但此时比对数据库记录版本时发现,操作员 B 提交的 
数据版本号为 2 ,数据库记录当前版本也为 2 ,不满足  提交版本必须大于记 
录当前版本才能执行更新  的乐观锁策略,因此,操作员 的提交被驳回。 
这样,就避免了操作员 用基于 version=1 的旧数据修改的结果覆盖操作 
员 A 的操作结果的可能。 
从上面的例子可以看出,乐观锁机制避免了长事务中的数据库加锁开销(操作员 A
和操作员 B 操作过程中,都没有对数据库数据加锁),大大提升了大并发量下的系 
统整体性能表现。 

展开阅读全文

没有更多推荐了,返回首页