基于乐观锁的幂等处理

2021-12-09  本文已影响0人  会飞的小猪

我们在实现幂等接口的时候,例如处理微信支付回调,一般来说可以根据如下逻辑来实现幂等操作。
伪代码

// 根据订单号查询订单是否存在
步骤1、Order order = orderService.getOrder(orderNo);
// 判断状态是否成功
步骤2、if (order!=null && !order.getStatus().equalsIgnoreCase("success")){
步骤3、    // 更新订单成功,以及后续业务逻辑等等
              }

假如同时过来两条请求,请求1和请求2的线程是可以同时走到步骤3的,此时系统会走两遍业务逻辑,对于金融业务来说这是不允许出现的。
那么有没有一种办法,既简单又可以避免这个问题呢。其实我们可以利用乐观锁的思想来实现幂等防并发问题。
控制层

Order order = orderService.getOrder(orderNo);
        if (order!=null && order.getStatus().equalsIgnoreCase("init")){
            order.setStatus("success");
            orderService.updateOrder(order);
        }

mybatis逻辑

update `order`
    set  status = #{status,jdbcType=VARCHAR},version=version+1
    where id = #{id,jdbcType=INTEGER}
    and version=#{version,jdbcType=INTEGER}

下面我们来测试下。

数据库记录 image.png
jmeter模拟100个并发
image.png

执行完数据库记录只更新了一次


image.png
乐观锁:
1.如果有人在你之前更新了,你的更新应当是被拒绝的,可以让用户重新操作。
2.实现:大多数基于数据版本(Version)记录机制实现

具体可通过给表加一个版本号或时间戳字段实现,当读取数据时,将version字段的值一同读出,数据每更新一次,对此version值加一。当我们提交更新的时候,判断当前版本信息与第一次取出来的版本值大小,如果数据库表当前版本号与第一次取出来的version值相等,则予以更新,否则认为是过期数据,拒绝更新,让用户重新操作。

上一篇 下一篇

猜你喜欢

热点阅读