资讯专栏INFORMATION COLUMN

业务上锁的应用

Scliang / 2945人阅读

摘要:锁业务场景针对一个赔付工单由底下小二发起当金额数量大于一定值以后针对这笔工单就会有层层审批风控先一个审批流审批主管审批财务审批这里就会存在种权限一审权限二审权限终审权限当这笔工单被小二提交以后就会给小二对应的创建一个审批任务在主

业务场景

针对一个赔付工单(由底下小二发起),当金额数量大于一定值以后,针对这笔工单就会有层层审批(风控),先YY一个审批流「TL审批」--->「主管审批」--->「财务审批」.这里就会存在3种权限「一审权限」「二审权限」「终审权限」,当这笔工单被小二提交以后就会给小二对应的TL创建一个审批任务,在主管的界面就可以看到相应的审批任务,主管可以点击通过或者拒绝

实现
    1.查询任务,判断当前角色是否有权限操作该笔任务,任务没有完结等一系列校验
    2.驱动状态机更新工单状态
    3.完结任务
    
异常场景
场景一

操作:主管疯狂点击通过按钮3次(前提是按钮点击一次不会灰显,就算灰显也可以通过模拟请求来实现)

异常情况:三个点击线程都运行完1,然后线程1驱动状态机(通过 + 当前状态:待TL审批)得到的结果是待主管审批,紧接着线程2驱动状态机(通过 + 当前状态:待主管审批)得到的结果是待财务审批,然后线程3再运行驱动状态机(通过 + 当前状态:待财务审批)得到的结果是出账成功(不考虑多次完结任务会出现异常)

异常分析:在该场景中,只要角色拥有「一审权限」就可以通过漏洞直接把该订单审核出账

解决方案:

细化状态机中的每个审核操作
1.查询任务,查询该笔任务对应当前操作类型(TL审批OR主管审批OR财务审批)
---这里不仅仅是「通过」操作,判断当前角色是否有对应操作权限
2.根据当前操作类型+当前状态驱动状态机
3.完结任务

在查询任务之前加一个全局锁,针对这笔工单进行全局锁定(更加优雅)

场景二

操作:一个角色同时拥有一审权限和二审权限,当他打开一个工单要进行一审,但是其它主管已经执行了一审的动作,并且更新了一些信息.因为该角色页面没有刷新获取不到更新的信息,然后点击了通过按钮

异常情况:点击通过按钮就相当于进行了二审,会造成该角色获取不到最新信息而产生误判

解决方案:在场景一增加一个全局锁的前提下,可以给页面传递一个工单modifyTime,在全局锁里面判断modifyTime是否一致,如果不一致说明该笔工单已经被更新了,可以给用户相应的提醒

其它

在业务中整个状态机的流转都是确定的,所以为了保证状态流转正确,所以在更新数据库状态的时候,需要带上关于状态的乐观锁UPDATE XXX SET status = XXX WHERE id = XXX AND from_status = XXX

如果使用的是全局锁,那么每个操作工单的地方都需要加上相应的全局锁

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/26240.html

相关文章

  • 业务上锁应用

    摘要:锁业务场景针对一个赔付工单由底下小二发起当金额数量大于一定值以后针对这笔工单就会有层层审批风控先一个审批流审批主管审批财务审批这里就会存在种权限一审权限二审权限终审权限当这笔工单被小二提交以后就会给小二对应的创建一个审批任务在主 锁 业务场景 针对一个赔付工单(由底下小二发起),当金额数量大于一定值以后,针对这笔工单就会有层层审批(风控),先YY一个审批流「TL审批」--->「主管审批...

    stormzhang 评论0 收藏0
  • 聊聊 Redis 分布式锁正确实现

    摘要:在昨天队友代码的过程中,发现了我们组分布式锁的写法似乎有点问题,实现代码如下加锁部分解锁部分主要原理是使用了的去插入一组,其中要上锁的标识在项目中是锁死用户,如果上锁失败则返回。 最近在参加学校安排的实训任务,我们小组需完成一套分布式&微服务跨境电商,虽然这题目看起来有点老套,并且队友多是 Java 技术栈,所以我光荣(被迫) 的成为了一名前端,并顺路使用 PHP 的 Swoole 帮...

    imingyu 评论0 收藏0

发表评论

0条评论

Scliang

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<