java之悲观锁与乐观锁

现实际业务中会出现这样的一种情况

id    name            total

1     zhangsan     5

表数据为此,在正常情况下我们对这笔记录去处理update的操作

首先肯定是查出来这笔记录

然后再进行update操作  对total ++ 或 -- 操作;

 

但是如果并发情况下会出现这样的情况

我两条线程同时进入

然后同时查出来数据total都是5

然后第一条线程要对这个total + 5  那么total结果应该是10

由于是并发同时进入另一条线程查出来 这个total也应该是与第一条线程修改之前一样 total = 5

但是第二条线程要对total值进行 -3 的操作  那么total = 5 - 3 = 2 

然后不管两条线程谁先谁后最后这个total值可能是 2 或者 10 都不是我们想要的正确值

实际上我们想要的值应该是 5 - 3 + 5 = 7 (正确值) 

这时候数据库里面就存在了脏数据

 

锁机制可以解决这种问题

第一种:悲观锁(synchronized关键字)

synchronized可以修饰实例方法,静态方法,代码块。

如果在上面的方法上加上这个关键字那么就可以解决这种问题

但是synchronized关键字他是去锁住线程进入当前有且仅有一条线程可以进入

例如你去上厕所 厕所外面有一个大门你把大门给锁上了,里面其实有很多厕所可以使用你仅仅使用了一个

这样做就导致了系统处理性能变慢,不符合高并发高性能的理念

说他是悲观锁其实意思就是:我知道这个方法肯定会出错,那么我就把这个方法锁上

 

第二种:乐观锁

这种机制仅仅只需要在数据库上加上一个字段version

id    name            total   version

1     zhangsan     5        1

我每次去对这笔记录去进行update的操作就把version+1 并且你的update语句要带上version参数

这意思就是两条线程同时进入

第一条线程进入查询出来id = 1, total = 5, version = 1 我进行update操作对totalNew = total + 5  ,versionNew = version + 1

update table_name

set total = totalNew , version = versionNew

where id = id and version = version

记录就变成了

id    name            total   version

1     zhangsan     10       2

第二条线程进入由于是和第一条同时进入那么查询出来其实和第一条线程一样 total = 5 version = 1 

我进行update操作对totalNew = total - 2  ,versionNew = version + 1

update table_name

set total = totalNew , version = versionNew

where id = id and version = version

这时候线程二找不到这个version = 1 id = 1 的记录那么update的记录就为0

代码中接收到update返回为0 那么就可以进行操作失败的业务处理,至于重新执行或者返回提示就看业务了

这样做相对于悲观锁我既能够保证并发并且不会出现数据问题

 

并且现在好像有个什么规定尽量避免或者不使用悲观锁,毕竟悲观锁影响了系统的性能操作

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值