【安全】Java幂等性校验解决重复点击,BAT大厂网络安全面试真题锦集干货整 ...

打印 上一主题 下一主题

主题 861|帖子 861|积分 2583

乐观锁:乐观锁在操作数据时,非常乐观,以为别人不会同时在修改数据。因此乐观锁不会上锁,只是在执行更新的时候判定一下,在此期间是否有人修改了数据。
乐观锁的实现:
就是给表多加一列 version 版本号,每次更新数据前,先查出来确认下是不是刚刚的版本号,没有改动再去执行更新,并升级 version(version=version+1)。
比如,我们更新前,先查一下数据,查出来的版本号是 version=1。
select order_id,version from order where order_id=‘666’;
然后使用 version=1 和 订单ID 一起作为条件,再去更新:
update order set version = version +1,status=‘P’ where order_id=‘666’ and version =1
末了,更新成功才可以处理业务逻辑,如果更新失败,默以为重复请求,直接返回。
流程图如下:

为什么版本号发起自增呢?
   因为乐观锁存在 ABA 的题目,如果 version 版本一直是自增的就不会出现 ABA 的情况。
  3.3 数据库层面,悲观锁(select for update)【不保举】

悲观锁:通俗点讲就是很悲观,每次去操作数据时,都觉得别人中途会修改,所以每次在拿数据的时候都会上锁。官方点讲就是,共享资源每次只给一个线程使用,其他线程阻塞,用完后再把资源转让给其它资源。
悲观锁的实现:
   在订单业务场景中,假设先查询出订单,如果查到的是处理中状态,就处理完业务,然后再更新订单状态为完成。如果查到订单,并且不是处理中的状态,则直接返回。
  可以使用数据库悲观锁(select … for update)解决这个题目:
begin; # 1.开始事务
select * from order where order_id=‘666’ for update # 查询订单,判定状态,锁住这条记录
if(status !=处理中){
//非处理中状态,直接返回;
return ;
}
处理业务逻辑

update order set status=‘完成’ where order_id=‘666’ # 更新完成
commit; # 5.提交事务
留意:


  • 这里的 order_id 必要是主键或索引,只用行级锁锁住这条数据即可,如果不是主键或索引,会锁住整张表。
  • 悲观锁在同一事务操作过程中,锁住了一行数据。这样 别的请求过来只能期待,如果当前事务耗时比力长,就很影响接口性能。所以一般 不发起用悲观锁的实现方式
3.4 数据库层面,状态机

许多业务表,都是由状态的

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

花瓣小跑

金牌会员
这个人很懒什么都没写!
快速回复 返回顶部 返回列表