springboot项目避免脏读影响修改数据的几种方法

阅读: 评论:0

springboot项目避免脏读影响修改数据的几种方法

springboot项目避免脏读影响修改数据的几种方法

文章目录

    • 1.通过sql层面进行行锁
    • 2.通过cas原则(compareAndSwapInt)进行自旋
    • 3.通过synchronized锁住查询跟修改语句
    • 4.通过分布式锁redission

1.通过sql层面进行行锁

((1)Update时,where中的过滤条件列,如果用索引,锁行,无法用索引,锁表。按照索引规则,如果能使用索引,锁行,不能使用索引,锁表。
(2)Insert时,锁行。)

1.修改之前查询数据,通过select for update加上@transaction标签,查询的时候就锁住了这条数据,直到下面一句update语句执行结束
2.如果是增加固定的数值,比如点赞每次like加1,就可以这样写:update 表 set A=A+1 where XXX 这样就可以通过行锁解决
3.比如是账户余额扣款,不想让账户超额支付,可以再where条件后面加一个大于0,如果修改行数为0就说明扣款失败

2.通过cas原则(compareAndSwapInt)进行自旋

首先select出一个数值A,然后计算出改变后的数值B,UPDATE music_order SETstatus= B WHERE order_id='e2524882-23' ANDstatus= A

这样可以得到
当影响行数等于0的时候,就进行重试,直到成功

3.通过synchronized锁住查询跟修改语句

如果是单体springboot项目可以直接用synchronized锁住查询修改的语句

    public ResponseVO<Object> likeComment(Integer commentId) {//获取账户String account = (String) Cache("account");//锁越小越好synchronized (this) {//查询数据A//计算出B//update数据return ResponseVO.buildSuccess();}}

4.通过分布式锁redission

如果是分布式项目集群就可以用redission

@Transactional(rollbackFor = Exception.class)@Overridepublic void payOrder(OrderDTO orderDTO) {UserInformationDTO userBasic = UserBasic();//锁住用户支付的操作(维度是用户的账户)String key = "pay_order_lock_" + Account();RLock lock = Lock(key);lock.lock();try {//获取用户的财产信息UserPropertyPO userPropertyPO = payMapper.UserId());ResponseVO<List<OrderPO>> listResponseVO = feignService.queryMyOrder(orderDTO);List<OrderPO> result = Result();OrderPO orderPO = (0);BigDecimal orderMoney = OrderMoney();BigDecimal userMoney = Money();Integer compare = orderMoneypareTo(userMoney);//余额不足抛出异常if (compare == 1) {throw new MyException(ErrorCode.BALANCE_ERROR);}BigDecimal newUserMoney = userMoney.subtract(orderMoney);//扣款payMapper.UserId(), newUserMoney);//修改订单状态ResponseVO responseVO = feignService.OrderId());if (!"success".Message())) {throw new MyException(ErrorCode.FEIGN_ERROR);}//TODO:消息队列通知库存系统} catch (MyException e) {("出错{}", e.getMessage());if (ErrorCode.String().Message())) {throw new MyException(ErrorCode.BALANCE_ERROR);} else {throw new MyException(ErrorCode.FEIGN_ERROR);}} catch (Exception e) {("出错{}", e.getMessage());throw new MyException(ErrorCode.ERROR);} finally {lock.unlock();}}

本文发布于:2024-02-04 07:49:56,感谢您对本站的认可!

本文链接:https://www.4u4v.net/it/170702357553668.html

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。

留言与评论(共有 0 条评论)
   
验证码:

Copyright ©2019-2022 Comsenz Inc.Powered by ©

网站地图1 网站地图2 网站地图3 网站地图4 网站地图5 网站地图6 网站地图7 网站地图8 网站地图9 网站地图10 网站地图11 网站地图12 网站地图13 网站地图14 网站地图15 网站地图16 网站地图17 网站地图18 网站地图19 网站地图20 网站地图21 网站地图22/a> 网站地图23