金额数据修改避免脏读:使用mybatis的updateWrapper.setSql

本文介绍了一种正确处理会员佣金到账的方法,避免了脏读的问题。通过使用乐观锁机制,在数据库层面直接更新可提成奖金、累计奖金及预计到账奖金,确保了数据的一致性和事务的原子性。

需求:会员佣金到账,应该增加会员的可提成奖金、累计奖金,扣除对应的预计到账奖金

原先错误的写法会导致脏读:

 //更新师傅的可提现金额
            DistributionDO dist = this.distributionClient.getDistributorByMemberId(engineerId);
            if (oConvertUtils.isNotEmpty(dist)) {
                //提成佣金
                dist.setCanRebate(CurrencyUtil.add(dist.getCanRebate(), actualEngineerBonus));
                //累计佣金
                dist.setRebateTotal(CurrencyUtil.add(dist.getRebateTotal(), actualEngineerBonus));
                //扣除预计到账金额(冻结金额)
                //需要注意防止脏读,不可以直接把字段set,应该在sql里写
                double sub = CurrencyUtil.sub(dist.getCommissionFrozen(), parentBonus);
                if (sub > 0) {
                    dist.setCommissionFrozen(sub);
                } else {
                    dist.setCommissionFrozen(0.0);
                }

                this.distributionClient.edit(dist);

参考组长的写法:

组长说这样写法自带乐观锁

private void addEstimate(DistributionDO distributionDO, double estimateRebate) {
        UpdateWrapper<DistributionDO> updateWrapper = new UpdateWrapper<>();
        updateWrapper.setSql("commission_frozen = commission_frozen + " + estimateRebate);
        updateWrapper.eq("member_id", distributionDO.getMemberId());
        distributionMapper.update(null, updateWrapper);
    }

照虎画猫之后:

 /**
     * 佣金到账完成后的佣金变化方法
     *
     * @param memberId    归属会员ID
     * @param actualBonus 实际到账佣金
     * @param dueBonus    应到账奖金
     */
    @Override
    @Transactional(value = "memberTransactionManager", rollbackFor = Exception.class)
    public void bonusIntoAccount(Long memberId, Double actualBonus, Double dueBonus) {

        UpdateWrapper<DistributionDO> updateWrapper = new UpdateWrapper<>();
        //扣除预计到账金额(冻结金额)
        /* updateWrapper.setSql("commission_frozen = commission_frozen - " + dueBonus + ",can_rebate = commission_frozen + " + actualBonus + ",rebate_total = commission_frozen + " + actualBonus);*/
        updateWrapper.setSql("commission_frozen = commission_frozen - " + dueBonus);
        //提成佣金
        updateWrapper.setSql("can_rebate = can_rebate + " + actualBonus);
        //累计佣金
        updateWrapper.setSql("rebate_total = rebate_total + " + actualBonus);
        updateWrapper.eq("member_id", memberId);
        distributionMapper.update(null, updateWrapper);

    }

这里3个setSql是会拼接在一起。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值