赞
踩
@Service @Slf4j public class AccountTCCServiceImpl implements AccountTCCService { @Autowired private AccountMapper accountMapper; @Autowired private AccountFreezeMapper freezeMapper; @Override @Transactional public void deduct(String userId, int money) { // 0.获取事务id String xid = RootContext.getXID(); //1.判断freeze中是否有冻结记录,如果有,一定是CANCEL执行过,我要拒绝业务 AccountFreeze oldFreeze = freezeMapper.selectById(xid); if (oldFreeze != null){ //CANCEL执行过,我要拒绝业务 return; } // 1.扣减可用余额 accountMapper.deduct(userId, money); // 2.记录冻结金额,事务状态 AccountFreeze freeze = new AccountFreeze(); freeze.setUserId(userId); freeze.setFreezeMoney(money); freeze.setState(AccountFreeze.State.TRY); freeze.setXid(xid); freezeMapper.insert(freeze); } @Override public boolean confirm(BusinessActionContext ctx) { // 1.获取事务id String xid = ctx.getXid(); // 2.根据id删除冻结记录 int count = freezeMapper.deleteById(xid); return count == 1; } @Override public boolean cancel(BusinessActionContext ctx) { // 0.查询冻结记录 String xid = ctx.getXid(); String userId = ctx.getActionContext("userId").toString(); AccountFreeze freeze = freezeMapper.selectById(xid); //1.空回滚的判断,判断freeze是否为null,为null证明try没执行,需要空回滚 if (freeze == null){ freeze = new AccountFreeze(); freeze.setUserId(userId); freeze.setFreezeMoney(0); freeze.setState(AccountFreeze.State.CANCEL); freeze.setXid(xid); freezeMapper.insert(freeze); return true; } //2.幂等判断 if (freeze.getState() == AccountFreeze.State.CANCEL) { //已经处理过一次CANCEL,无需重复处理 return true; } // 1.恢复可用余额 accountMapper.refund(freeze.getUserId(), freeze.getFreezeMoney()); // 2.将冻结金额清零,状态改为CANCEL freeze.setFreezeMoney(0); freeze.setState(AccountFreeze.State.CANCEL); int count = freezeMapper.updateById(freeze); return count == 1; } }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。