悲观锁和乐观锁只适用于更新操作。
使用哪种机制,取决于你的场景,本质上原则和目标:提高写效率。
悲观锁是避免冲突,乐观锁是检验冲突。
若存在大量冲突的情况下,使用悲观锁的效率会更高。
概念
悲观锁:每次改变数据时,都担心数据被修改。故在悲观锁的环境中,在改变对象之前就将该对象锁住,直到你提交更改后才释放锁。悲观锁的缺点在于可能会长时间限制其他用户的访问,也就是说悲观锁的并发访问性不好。
乐观锁:每次更改数据时,不担心数据被修改。因此乐观锁在提交更改时才会将对象锁住,当读取或改变对象时并不加锁。可见乐观锁加锁时间比悲观锁短,乐观锁加锁粒度比较小。但是在你提交改变时,发现对象已经被改变,于是你不得不重新读取该对象并作出改变(自旋操作)这说明在乐观锁环境中,会增加并发用户读取对象的数量。
如何抉择
乐观锁可以提供并发访问的效率,但是如果出现了冲突只能向上抛出,然后重来一遍;悲观锁可以避免冲突的发生,但是会降低效率。
选择使用哪一种锁取决于冲突频率和一旦发生冲突的严重性。如果系统并发访问冲突的频率很低或者冲突发生后的后果并不严重(所谓后果应该就是被检测到冲突的提交会失败,必须重来一次),可以使用乐观锁,否则使用悲观锁。
适用场景
实际上,无论是悲观锁还是乐观锁,都是update(行级锁)操作。悲观锁语法是select * from table for update
预先加锁,防止其他用户访问。而乐观锁,本质上是检测冲突(检测是否发生改变),而非预防冲突。一般使用版本号控制。
一般来说,我们业务操作,一般在接受请求后,登记流水表(状态"未处理")。而在响应的时候,需要更新流水表(一个条件便是状态),此时便是使用了乐观锁:在提交改变时检测是否冲突。
网友评论