高并发下乐观锁实现

目前有业务并发更新某业务表,好比用户帐户表,可考虑利用数据库乐观锁的办法解决。数据库

一、表设计mybatis

     须要在表中新增version字段,可定义为bigint类型,初始值可设置为0并发

二、更新语句mybatis的实现app

<update id="updateConsumeStarWithLook">
        update sys_user_consume_star 
            set current_consume_star_amount = #{currentConsumeStarAmount},
                update_time = #{updateTime, jdbcType=TIMESTAMP},
                version = version + 1
            where id = #{id} and version = #{version}
    </update>

三、业务逻辑层,实现思路:可定义一个更新方法,先查询出当前记录,根据业务进行调用乐观锁实现的updateConsumeStarWithLook,若是更新成功,即该返回值为1时,表示更新成功,当返回值为0时,表示未成功更新,可再次递归调用该更新方法。测试

private void updateUserConsumeStarWithLook(String userId,Long starAmount) { Wrapper<SysUserConsumeStar> wrapper = new QueryWrapper<SysUserConsumeStar>() .eq("user_id", userId); SysUserConsumeStar sysUserConsumeStar = sysUserConsumeStarService.getOne(wrapper); Long oldStartAmount = sysUserConsumeStar.getCurrentConsumeStarAmount(); Long newStartAmount = oldStartAmount + starAmount; sysUserConsumeStar.setCurrentConsumeStarAmount(newStartAmount).setUpdateTime(LocalDateTime.now()); Integer result = sysUserConsumeStarService.updateConsumeStarWithLook(sysUserConsumeStar); //若是更新失败则继续尝试直到成功为止
        if(result == 0) { updateUserConsumeStarWithLook(userId,flowType,starAmount); } }

四、在具体调用上述方法的方法上若是须要加上事务,则须要将事务的隔离级别定义为读已提交,否则在查询的时候会出现脏读,更新没法成功,致使死循环spa

@Transactional(rollbackFor = Exception.class,isolation=Isolation.READ_COMMITTED,propagation=Propagation.REQUIRED)

 五、测试,可以使用JMater,相关教程可参考:https://blog.csdn.net/u010481688/article/details/81032259.net

相关文章
相关标签/搜索