乐观锁和悲观锁的区别有什么?有什么作用?

一提到java语言中的锁机制,我们可能第一反应就是乐观锁悲观锁了。那么你清楚乐观锁和悲观锁的区别都有什么吗?它们有什么作用呢?

一、悲观锁(Pessimistic Lock):

就是每次去拿数据的时候都认为别人会修改掉数据,所以呢,每次在拿数据的时候都会为数据上锁,这样的话别人想拿这个数据就会block直到它拿到了锁。传统的关系型数据库里面就用到了很多这种锁机制呢,比如行锁,表锁等等,读锁,写锁等等,都是在做操作之前先上锁的。

二、乐观锁(Optimistic Lock)

就是每次去拿数据的时候都认为别人不会修改数据,所以就不会给数据上锁,但是在更新的时候可能会判断一下在此期间别人有没有去更新这个数据,我们可以使用版本号等机制。

乐观锁更适用于多读的应用类型,这样可以还可以提高吞吐量,像数据库如果提供类似于write_condition的机制的其实都是提供的乐观锁的。

两种锁也是各有优缺点的,不可以认为一种好于另一种哦,像乐观锁就比较适用于写比较少的情况下,就是冲突真的很少发生的时候,这样还可以省去了锁的开销,加大了系统的整个吞吐量了。但如果经常产生冲突的话,上层应用会不断的进行retry,这样反而是降低了性能了,所以这种情况下可能使用悲观锁就比较合适了。

其实本质上,数据库的乐观锁做法和悲观锁做法主要就是解决下面假设的场景,避免丢失更新问题:

假设当当网上一位用户下单买了本书,这时数据库中有条订单号为001的订单,其中有个status字段是‘有效’,表示该订单是有效的;

当后台管理人员查询到这条001的订单时,并且看到状态是有效的。

可是·用户发现下单的时候下错了,于是就撤销了订单,假设运行这样一条SQL语句:update order_table set status = ‘取消’ where order_id = 001;

后台管理人员由于在b这步看到状态有效的,这时,虽然用户在c这步已经撤销了订单,可是管理人员并未刷新界面,看到的订单状态还是有效的,于是点击”发货”按钮,将该订单发到物流部门,同时运行类似如下SQL,将订单状态改成已发货:update order_table set status = ‘已发货’ where order_id = 001

所以只有冲突非常严重的系统才需要悲观锁;“所有悲观锁的做法都适合于状态被修改的概率比较高的情况,具体是否合适则需要根据实际情况判断。”,表达其实的也是这个意思,不过说法不够准确了;也是,之所以用悲观锁,就是因为两个用户更新同一条数据的概率高了,也就是冲突比较严重的情况下,所以才用悲观锁的。

好了,以上就是本篇文章的所有内容了,还想了解更多java常见问答信息,记得关注本站消息。

推荐阅读:

乐观锁和悲观锁的实现要如何配置?具体概念是什么?

乐观锁实现方式有几种?乐观锁是什么?

springcloud和springboot的区别是什么?