悲观锁与乐观锁

来源:互联网 发布:crt结束tomcat端口 编辑:程序博客网 时间:2024/05/29 03:06


悲观锁与乐观锁都是对被修改数据在并发情况下的一种保护机制;这里悲观与乐观的含义是指对于即将修改的数据被外界修改持一种悲或乐的态度;即:悲观锁是指我认为当我要修改一个数据的时候,别人也在修改,所以我要对即将操作的数据进行全程加锁,以保证我的操作不会被别人所影响;乐观锁是指当我要修改数据的时候,别人一般不会再修改,因此,我只在提交我的修改时再加锁,而不用全程加锁。由此可见:悲观锁的加锁时间更长。

对于修改数据,在很多场景下不是一上来就修改,例如:有两个数据a和b,它们之间存在这样的关联关系:如果a的值为奇数,则b的值为1,如果a的值为偶数,则b的值为0;在某个场景下,需要修改b时,就需要做如下事情:

(1)      取到a的值;

(2)      根据a的值,算出b应该被设置的值;

(3)      提交对b的修改;

对于乐观锁,他对于步骤(1)(2)不加锁,只在步骤(3)提交对b的修改时才进行加锁;对于悲观锁,它对步骤(1)、(2)、(3)全部都加锁。

悲观锁与乐观锁的使用场景:

(1)      悲观锁适用于写多读少的场景;

(2)      乐观锁适用于读多写少的场景;

对于悲观锁,它非常简单粗暴,不管三七二十一上来就锁数据,因此它非常容易实现;乐观锁假定在自己修改的时候,别人不会修改,可是一旦别人进行了修改,需要采用何种技巧性的策略来保证数据安全性呢?其中一种常见的实现方式是:对数据加上版本号进行控制;个人理解其大概的实现方案如下所示:

数据的有一个集中管理的地方,任何对数据的修改都要将请求转发给数据管理,由数据管理中心统一对所有的修改进行管理;应用在对数据修改的时候,步骤如下:

(1)      要先读取数据及其对应的版本号;

(2)      修改数据,并将版本号+1;

(3)      将数据以及新的版本号提交给数据管理中心;

(4)      数据管理中心接到修改提交之后,检查提交的数据的版本号与当前数据的版本号,如果当前版本号大于等于提交的版本号,说明数据已经被其他人修改了,则要给当前的这个修改请求返回失败;

(5)      数据提交方需要对修改请求的失败结果进行特殊处理,例如向用户返回失败,或者再次从步骤(1)开始尝试。

如果误用了悲观锁或者乐观锁会有什么影响?

(1)      本应用乐观锁的场景下使用了悲观锁,即:在读多写少的场合中使用了悲观锁;此时,由于悲观锁加锁时间较长,它会阻碍其他的读请求,让大量的读请求阻塞,进而影响整个系统的性能,造成系统的读写请求的并发量下降。

(2)      本应用悲观锁的场景下使用了乐观锁,即:在写多读少的的场合中使用了乐观锁;此时,由于乐观锁只在提交修改的时候才加锁,在大量写请求也在同时发生的时候,你大多数提交的请求极可能会失败,因为在你修改数据的时候或者之前很多时间内,其他用户已经把数据修改了。

0 0