情景
现在有两个仓库管理员A和B,他们共同管理一个仓库,仓库里有10件商品。A收到一条通知要取1件商品,B也收到一条通知要取2个。A去仓库一查有10件,他取了一件。在他修改仓库前,B来了一查仓库有10个取了两个,A更新仓库将才仓库更新为9,B也更新仓库将仓库更新为8。此时仓库的个数为8(B将A更新的覆盖了)而仓库实际的个数为7个。如果一直这样下去的话一定会出现问题。
解决方法一(悲观锁)
悲观锁就是在他们在任何一个人取的时候要将仓库加上锁不允许别人操作。也就说,当A操作仓库的时候将仓库加了一把锁.B看到锁后B明白有人在操作,那么B就不会操作仓库,B就会一直等到A操作完B才可以操作。在A的心态很悲观,他老是认为在他操作的时候总有人来操作仓库,所以A加了一把锁。这把锁就是悲观锁,上面所述的就是悲观锁的思路。这样做确实解决了一些问题但是如果锁的时间太长,其他用户会等待很长时间。
解决方法二(乐观锁)
乐观锁是相对与悲观锁的存在的,也就是说,A和B达成了一个协议,而且A很乐观他认为其他人不会来操作仓库所以他没有加锁,但是他们操作仓库的时候多加一个字段如仓库的版本(还可以是时间戳),当A操作的时候仓库的版本为1,仓库的数量为10。每次当操作仓库的时候读的时候不仅要读出仓库的数量还要读出仓库的版本。当你往回写的时候看一下版本是否一致,如果一致的话就直接写回去,如果不一致的话将放弃本次的操作从新来。这就是乐观锁,也就是说在任何人操做数据只有在更新的时候才去看是否有冲突。但是呢这样也会有问题如果冲突数量过多的时候,会不断的去操作数据,会降低性能。
乐观锁和悲观锁都是思考问题的一种方式,并不只局限于数据库的应用。还有其他的应用:例如CAS和线程同步等。