今天做测试,发现在public方法上添加注解@Transactional事物不生效,网上查了很多的事物不生效的案例。我都符合标准的呀。为什么事物不生效呢?仔细检查之后才发现自己的错误。异常不能被try catch 掉。要抛到事务方法上去。我try catch掉异常了。当然事务不生效了。
案例:这样事务是不回滚的
@Transactional(rollbackFor = Exception.class) public RocketMQLocalTransactionState executeLocalTransaction(Message message, Object o) { try { //解析message,转成AccountChangeEvent String messageString = new String((byte[]) message.getPayload()); JSONObject jsonObject = JSONObject.parseObject(messageString); String accountChangeString = jsonObject.getString("accountChange"); //将accountChange(json)转成AccountChangeEvent AccountChangeEvent accountChangeEvent = JSONObject.parseObject(accountChangeString, AccountChangeEvent.class); //执行本地事务,扣减金额 accountInfoService.doUpdateAccountBalance(accountChangeEvent); //模拟异常,这个异常被catch住了,事务不会生效,数据不会回滚 if(accountChangeEvent.getAmount() == 2) { //int i = 1 / 0; throw new RuntimeException("人工异常"); } //当返回RocketMQLocalTransactionState.COMMIT,自动向mq发送commit消息,mq将消息的状态改为可消费 return RocketMQLocalTransactionState.COMMIT; } catch (Exception e) { log.error("执行本地事物异常:{}", e); return RocketMQLocalTransactionState.ROLLBACK; } }
案例:这样,事务才会回滚
@Override @Transactional public void doUpdateAccountBalance(AccountChangeEvent accountChangeEvent) { //幂等判断 if(accountInfoDao.isExistTx(accountChangeEvent.getTxNo())>0){ return ; } //扣减金额 accountInfoDao.updateAccountBalance(accountChangeEvent.getAccountNo(),accountChangeEvent.getAmount() * -1); //添加事务日志 accountInfoDao.addTx(accountChangeEvent.getTxNo());
//事务生效,数据回滚 if(accountChangeEvent.getAmount() == 3){ throw new RuntimeException("人为制造异常"); } }
参考: