小白科普:悲观锁和乐观锁

转自:码农翻身(微信号:coderising)

一、无锁
旺财和小强生活在一个网上商城的系统中, 是一对儿线程好基友。

星期一刚上班,旺财接到领导电话说,要把一个商品的库存减小20, 旺财不敢怠慢,赶快把库存取出来一看,哦,如今有1000个。

与此同时,小强也接到电话说要把同一商品的库存减小30, 他一看,哦,如今有1000个。

旺财计算出最新的库存值980, 保存!

小强也计算出最新的库存值970, 保存 !  

旺财的数据被小强覆盖了!

领导一看,原本卖出了50个商品,如今库存只扣了30个,这样持续下去就天下大乱了。

旺财和小强, 各打二十大板, 长长记性!

二、悲观锁
小强说:“哥,要不咱们仍是想个办法吧,再这样下去要被打死的。”

旺财悲催地说: “这样, 之后咱们每次访问库存以前,都要先加锁,加了锁,就禁止别人再进入访问,只能等待持有锁的人来释放。”

星期二, 领导让旺财再次把库存减小20 , 旺财此次万分当心,先把库存给锁住,而后慢慢修改。

小强也接到了把库存减小的指令, 可是旺财哥已经把库存锁住了, 不能操做,小强只好去阻塞车间喝茶聊天,而后到就绪车间等待调度运行。

好不容易等到能够再次执行了,小强一看,这库存怎么还锁着呢!? 只好再次去阻塞车间喝茶。

领导一看, 小强你怎么回事, 总是喝茶聊天? !  还干不干活了?

小强争辩说旺财哥一直锁着库存,我无法操做。

领导无论这些, 把小强和旺财又打了二十大板。

(备注: 这种加锁的方式就是悲观锁了,悲观锁正如其名,每次取读写数据时候总认为数据会被别人修改,因此将数据加锁,置于锁定状态, 不让别人再访问。缺点是若是持有锁的时间太长,其余用户须要等待很长时间。)

三、乐观锁
旺财说: “兄弟,这一次哥对不住你啊,处理得慢了一些, 不过哥刚才挨打的时候想了一个好办法:乐观锁。”

小强说:“拉倒吧你,屁股都快被打烂了还乐观?”

“你听我说嘛, 咱们在那个库存字段的旁边,再加上一个版本(version)的字段, 例如刚开始的时候(库存= 1000, 版本=1), 每次你去读的时候不只要读出库存,还要读出版本号, 等到你修改了库存,往回写的时候必定要检查一下版本号,看看和你读的时候是否同样。”

“若是不同呢?”  小强问

“那就放弃此次写的操做,从新读取库存和版本号, 从新来过。”

“若是同样呢? ”

“那就放心大胆地把新的库存值写回去。把版本号也加1”

“我彷佛有点明白了,咱们试试,不过你要想好,我可不想再挨板子了。”

星期三, 旺财奉命把库存减去30, 他先读到了(库存= 1000, 版本=1);  小强也要改库存了,他要把库存减去50, 因而他也读到了(库存= 1000, 版本=1)。

旺财计算出新的库存值970 ,写回成功,如今版本变成了(库存= 970, 版本=2)。

小强也计算出新库存950 , 也准备写回,他战战兢兢地去看最新的版本号, 已经变成版本2了, 按照以前的约定,只好从新读取了。

小强再次读取(库存= 970, 版本=2) , 计算出最新缓存值920(970减去50), 再次试图更新,没想到又被别人抢了先,如今版本号已经变成3了,最新的数据是(库存= 900, 版本= 3)。

唉, 只好从新来过, 计算出最新缓存值850(900减去50),第三次终于更新成功了, 最新的库存是 (库存=850, 版本= 4)

领导看到旺财和小强忙得热火朝天,一刻不停,而且库存值也没有乱掉, 满意地点了点头:好同志啊。

(备注: 这种方式就是所谓的乐观锁了,旺财和小强此次乐观了一点,以为通常状况下不会有太多人修改库存,因此没有加锁,放心地去操做,只有在最后更新的时候才去看是否冲突。 这种方式适合于冲突很少的场景,若是冲突不少,数据争用激烈,会致使不断地尝试,反而下降了性能。)

四、成功案例

缓存

相关文章
相关标签/搜索