seata1.4 全局事务失效配置

springcloud +seata 1.4 分布式事务,全局事务xid传递给每个方法,解决事务回滚问题


 /**
     * 新增公告
     * 
     * @param notice 公告信息
     * @return 结果
     */
    @Override
    @GlobalTransactional
    public int insertNotice(SysNotice notice)
    {
         try {
                log.info("Seata全局事务id insertNotice =================>{}", RootContext.getXID());
                String xid = RootContext.getXID();
                noticeMapper.insertNotice(notice);
                SysJobTest sysJobTest=new SysJobTest();
sysJobTest.setXid(xid);
                sysJobTest.setJobName("整数关口发送邮件提醒11");
                sysJobTest.setConcurrent("1");
                sysJobTest.setJobGroup("DEFAULT");
                sysJobTest.setInvokeTarget("ryTask.ryNoParams");
                sysJobTest.setCronExpression("0/15 * * * * ?");
                sysJobTest.setStatus("1");
                sysJobTest.setMisfirePolicy("3");
                
                remoteJobService.addTest(sysJobTest);
             int p=1/0;

         }catch (Exception e){

             try {
                 GlobalTransactionContext.reload(RootContext.getXID()).rollback();
             } catch (TransactionException e1) {
                 e1.printStackTrace();
             }

             e.printStackTrace();
         }
        return 1;
    }


@Override
    @Transactional
    public int addTest(SysJob job) {
        try{
            RootContext.bind(job.getXid());
            log.info("Seata全局事务id insertJobTest =================>{}", RootContext.getXID());
            job.setStatus(ScheduleConstants.Status.PAUSE.getValue());
            int rows = jobMapper.insertJob(job);

            return rows;
        }catch (Exception e){
                try {
                    GlobalTransactionContext.reload(RootContext.getXID()).rollback();
                } catch (TransactionException e1) {
                    e1.printStackTrace();
                }
        }
        return 1;
    }


在调用方法中直接传参全局事务xid 给下游服务

===============服务A
@Service
public class ServiceAImpl implements IServiceA
{
 
    private static final Logger log = LoggerFactory.getLogger(ServiceAImpl.class);
 
    @Autowired
    private IServiceB serviceB;
    @Autowired
    private IServiceC serviceC;
    
    @Override
    @GlobalTransactional
    @Transactional
    public Boolean doA() {
        String XID = RootContext.getXID();
        serviceB.doB(XID);
        serviceC.doC(XID);
        //......
    }
 
}
 
===============服务B
@Service
public class ServiceBImpl implements IServiceB
{
 
    private static final Logger log = LoggerFactory.getLogger(ServiceBImpl.class);
 
    @Override
    @Transactional(propagation = Propagation.REQUIRES_NEW)
    public Boolean doB(XID) {
        RootContext.bind(XID);
        //......
    }
 
}
 
===============服务C
@Service
public class ServiceCImpl implements IServiceC
{
 
    private static final Logger log = LoggerFactory.getLogger(ServiceCImpl.class);
 
    @Override
    @Transactional(propagation = Propagation.REQUIRES_NEW)
    public Boolean doC(XID) {
        RootContext.bind(XID);
        //......
    }
 
}




  

二、undo_log表有脏数据
当Seata没有正常结束时,每个服务对应数据库中的undo_log表和seata持久化数据库的brach_table、global_table、lock_table、undo_log表都有可能有脏数据没有正确删除,从而导致服务一直回滚,却不成功

解决办法:清除undo_log表以及seata持久化数据库的brach_table、global_table、lock_table、undo_log表中的脏数据

三、Fegin调用使用了Fallback降级或抛出的异常被全局处理
这种情况下属于seata服务发现不了下游服务抛出的异常,导致事务不会触发回滚

解决办法:

(1)通过 GlobalTransactionContext.reload(RootContext.getXID()).rollback() 进行手动回滚

===============服务A
@Service
public class ServiceAImpl implements IServiceA
{
 
    private static final Logger log = LoggerFactory.getLogger(ServiceAImpl.class);
 
    @Autowired
    private IServiceB serviceB;
    @Autowired
    private IServiceC serviceC;
    
    @Override
    @GlobalTransactional
    @Transactional
    public Boolean doA() {
        Integer bStatus = serviceB.doB();
        if(bStatus == 0){//在Mybatis中,返回值为0证明插入失败
            //手动回滚
            GlobalTransactionContext.reload(RootContext.getXID()).rollback();
            return false;
        }
        Integer cStatus = serviceC.doC();
        if(cStatus == 0){//在Mybatis中,返回值为0证明插入失败
            //手动回滚
            GlobalTransactionContext.reload(RootContext.getXID()).rollback();
            return false;
        }
        //......
    }
 
}
 
===============服务B
@Service
public class ServiceBImpl implements IServiceB
{
 
    private static final Logger log = LoggerFactory.getLogger(ServiceBImpl.class);
 
    @Override
    @Transactional(propagation = Propagation.REQUIRES_NEW)
    public Boolean doB() {
        //......
        Integer insertStatus = serviceBDAO.insert();
        return insertStatus;
    }
 
}
 
===============服务C
@Service
public class ServiceCImpl implements IServiceC
{
 
    private static final Logger log = LoggerFactory.getLogger(ServiceCImpl.class);
 
    @Override
    @Transactional(propagation = Propagation.REQUIRES_NEW)
    public Boolean doC() {
        //......
        Integer insertStatus = serviceCDAO.insert();
        return insertStatus;
    }
 

springcloud +seata 1.4 分布式事务,全局事务xid传递给每个方法,解决事务回滚问题

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值