栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

seata1.4 全局事务失效配置

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

seata1.4 全局事务失效配置

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


 
    @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传递给每个方法,解决事务回滚问题

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/936781.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号