mybatis plus的乐观锁使用总结

近期由于小并发量,项目组决定在某个表加个乐观锁。由于对mybatis plus的认知不是很到位,我一开始手写sql用最原始的方法去处理乐观锁,刚开始上线时没有问题,但是后来有同事在我的实体类对象用了mybatis plus的@version注解后,我的代码就直接崩溃了。找到原因后,为了防止以后又踩坑,所以记录了这篇文章。

一开始的原生代码如下(实体类,业务代码、sql):

@Data
@Builder
@TableName("xxx_account")
@AllArgsConstructor
@NoArgsConstructor
public class XXXAccount implements Serializable {
    private static final long serialVersionUID = 1L;

    private Integer id;
    @TableField("user_id")
    private Long userId;
    private String currency;
    private BigDecimal total;
    @TableField("transfer_frozen")
    private BigDecimal transferFrozen;
    private Integer version;
    @TableField("create_time")
    private Date createTime;
    @TableField("update_time")
    private Date updateTime;
}
 public void out(Integer id,TransferDto transferDto) throws Exception {
  		xxxAccount account = accountMapper.selectById(id);
       BigDecimal fundTotal = account.getTotal();
       account .setTotal(fundTotal.subtract(transferDto.getNum()));//减少可用总数量
       accountMapper.updateById(walletFundAccount);
       Integer result2 = accountMapper.changeMoney(account );
       if(result2 <= 0){
           throw new Exception("资金账户划转法币账户失败");
       }
   }
<update id="changeMoney">
       UPDATE xxx_account
       SET
           total = #{total},
           update_time = now(),
           version = version + 1
       WHERE id = #{id} AND version = #{version}
   </update>

代码写到这里,正常的话是没有问题的
燃鹅。。。。。。。。。。。。。同事加了mybatis plus的乐观锁(@version注解)后,就一直会更新失败

同事代码(伪代码):

@Configuration
public class VersionLockConfig {
    @Bean
    public OptimisticLockerInterceptor optimisticLockerInterceptor() {
        return new OptimisticLockerInterceptor();
    }

}

实体类加了个乐观锁注解

@Version
private Integer version;
//获取对象
xxxAccount a = accountMapper.selectById(id);
//需要修改的字段
xxxAccount xxx = new xxxAccount ();
xxx .setId(a.getId());
xxx .setVersion(a.getVersion())
xxx .setTotal(1000)
//修改
accountMapper.updateById(xxx )

同事代码接这样子结束了(简单讲解一下逻辑 1:加上mybatis plus乐观锁的配置 2:在实体类对象的version字段上面加上@version注解 3:用mybatis plus的update方法修改对象)
他的代码测试是对的,数据库对应的数据成功修改了,version也会+1。
但是。。我的代码却出了问题,永远不会修改成功,因为mybati是 plus会对对象的版本号进行修改,版本号对应不上,所以就永远更新不成功。

查询了mybatis plus的官网,https://mp.baomidou.com/guide/optimistic-locker-plugin.html#主要适用场景
虽然官网没有解释为什么加了@version的注解后,会对原生乐观锁的写法照成冲突。但是从官网里面找到了一些线索。就是加了@version注解后,mybatis plus会对这个版本号进行管理。
在这里插入图片描述
于是,我试想,将version交又mybatis plus管理后,不需要再自己去维护这个字段,所以试着将sql里面的版本号去掉
在这里插入图片描述

结果如预期所料,mybatis plus已经自己去维护这个字段了,数据能够成功更新,并且版本号会+1。

结论:
1.使用了mybatis plus的乐观锁后,自己写sql更新内容时,不要再加where version = xxx条件,也不需要手动给version + 1,mybatis会给我们做这件事情。自己再去维护会适得其反,只会导致更新永远是失败的。
2.也可以参照官网的例子,完全使用mybatis提供的方法去操作,会更加简单方便。

  • 7
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值