RocketMQ事务中sendMessageInTransaction方法带来的本地事务回滚失败问题

假如发送事务消息为SEND_OK,开始执行本地事务

本地事务是业务和事务日志表放一起的,处于一个事务中。

    @Transactional
    @Override
    public void createOrder(OrderDTO orderDTO,String transactionId){
 
        //1.创建订单
        Order order = new Order();
        BeanUtils.copyProperties(orderDTO,order);
        orderMapper.createOrder(order);
 
        //2.写入事务日志
        TransactionLog log = new TransactionLog();
        log.setId(transactionId);
        log.setBusiness("order");
        log.setForeignKey(String.valueOf(order.getId()));
        transactionLogMapper.insert(log);
 
        logger.info("订单创建完成。{}",orderDTO);
    }
    @Override
    public LocalTransactionState executeLocalTransaction(Message message, Object o) {
     createOrder(OrderDTO orderDTO,String transactionId);
     .................
}

但是由于spring的事务注解机制,假如你补获了异常,上面的的事务是失效的,就会导致业务成功,日志失败。Rocket源码sendMessageInTransaction()方法是调用你上面的监听方法的并补获了异常的。这是个隐藏的极大隐患问题

    //如果发送事务消息状态为send_ok
    case SEND_OK:
        try {
            //执行本地事务方法
            if (transactionListener != null) {
                this.log.debug("Used new transaction API");
                localTransactionState = transactionListener.executeLocalTransaction(msg, arg);
            }
        } catch (Throwable var10) {
            this.log.info("executeLocalTransactionBranch exception", var10);
            this.log.info(msg.toString());
            localException = var10;
        }
        break;

解决,重写TransactionMQProducer 实例的sendMessageInTransaction()方法里的这部分方法,手动抛出异常,让spring事务捕获到

    try {
        //执行本地事务方法
        if (transactionListener != null) {
            this.log.debug("Used new transaction API");
            localTransactionState = transactionListener.executeLocalTransaction(msg, arg);
        }
    } catch (Throwable var10) {
        this.log.info("executeLocalTransactionBranch exception", var10);
        this.log.info(msg.toString());
        localException = var10;
        throw new MQClientException(e.getMessage(),e);
    }   
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值