【已解决】SpringBoot集成Fescar0.4.0分布式事务事务不回滚如何解决

参考的文章:

https://blog.csdn.net/kris1122/article/details/88554452#commentBox

我按照如上的配置进行了测试,却没有实现回滚,感觉没有代理上数据源,不知如何处理?
发起请求时能够获取xid,如下:
全局事务id :192.168.13.55:8091:2006856911

应该和server也进行了通信
com.alibaba.fescar.core.rpc.netty.TmRpcClient:265 -> will send ping msg,channel[id: 0x8e0ac5a1, L:/192.168.13.55:52261 - R:/192.168.13.55:8091]
但是server端只有如下日志:
其中resourceIds='null',是不是此处存在问题?应该如何解决?谢谢!!!
 -rm register success,message:RegisterRMRequest{resourceIds='null', applicationId='dubbo-gts-fescar-example', transactionServiceGroup='my_test_tx_group'},channel:[id: 0xb984aef2, L:/127.0.0.1:8091 - R:/127.0.0.1:52174]
 -checkAuth for client:192.168.13.55:52261 vgroup:my_test_tx_group ok

表undo_log中好像一直没有存入数据

【已解决】SpringBoot集成Fescar0.4.0分布式事务事务不回滚如何解决_第1张图片

通过断点,数据源已经注入进来了

下面的sqlSessionFactory方法没有执行,不知是否有影响

【已解决】SpringBoot集成Fescar0.4.0分布式事务事务不回滚如何解决_第2张图片

============================问题原因============解决办法===================================

问题原因:

没有注意到工程中已经有一个数据源的配置类DataSourceConfig,导致FescarConfig没有起作用

【已解决】SpringBoot集成Fescar0.4.0分布式事务事务不回滚如何解决_第3张图片

解决办法:

将FescarConfig中的内容合并到原有的DataSourceConfig类中,对于activiti6工作流的配置创建ActivitiConfig进行设置,具体如下:

DataSourceConfig.java

 

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import javax.sql.DataSource;
import org.activiti.engine.ProcessEngine;
import org.activiti.spring.SpringProcessEngineConfiguration;
import org.apache.ibatis.session.SqlSessionFactory;
import org.mybatis.spring.SqlSessionFactoryBean;
import org.mybatis.spring.SqlSessionTemplate;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.core.env.Environment;
import org.springframework.core.io.Resource;
import org.springframework.core.io.ResourceLoader;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import com.alibaba.druid.filter.Filter;
import com.alibaba.druid.pool.DruidDataSource;
import com.alibaba.druid.spring.boot.autoconfigure.DruidDataSourceBuilder;
import com.alibaba.druid.wall.WallFilter;
import com.alibaba.fescar.rm.datasource.DataSourceProxy;
import com.alibaba.fescar.spring.annotation.GlobalTransactionScanner;

@Configuration
//@EnableTransactionManagement(proxyTargetClass = true)
@MapperScan(basePackages = {"com.yxkj.dao.mybatis"}, sqlSessionFactoryRef = "sqlSessionFactory")
public class DataSourceConfig {
    @Autowired
    private  WallFilter wallFilter;
    @Primary
    @Bean(name = "dataSource")
    public DataSource dataSource(Environment environment) {
        DataSource ds=DruidDataSourceBuilder
        .create()
        .build(environment, "spring.datasource.druid.");
        List filters = new ArrayList<>();
        filters.add(wallFilter);
        ((DruidDataSource)ds).setProxyFilters(filters);
        return ds;
//        DataSource dataSource=DataSourceBuilder.create().type(DruidDataSource.class).build();
//        List filters = new ArrayList<>();
//        filters.add(wallFilter);
//        ((DruidDataSource)dataSource).setProxyFilters(filters);
//        return dataSource;
    }
    
    /**
     * 包装数据源代理,用于在执行SQL之前生成回退日志
     * @Param: druidDataSource datasource bean instance
     * @Return: DataSourceProxy datasource proxy
     */
    @Bean(name = "dataSourceProxy")
    public DataSourceProxy dataSourceProxy(DataSource dataSource) {
        return new DataSourceProxy((DruidDataSource) dataSource);
    }


    @Primary
    @Bean(name = "transactionManager")
    public DataSourceTransactionManager transactionManager(@Qualifier("dataSourceProxy") DataSourceProxy dataSourceProxy) {
        return new DataSourceTransactionManager(dataSourceProxy);
    }

    @Primary
    @Bean(name = "sqlSessionFactory")
    public SqlSessionFactory sqlSessionFactory(@Qualifier("dataSourceProxy") DataSourceProxy dataSourceProxy) throws Exception {
      SqlSessionFactoryBean factoryBean = new SqlSessionFactoryBean();
      factoryBean.setDataSource(dataSourceProxy);
      String path = "classpath*:com/yxkj/dao/mybatis/**/*Mapper*.xml";
      org.springframework.core.io.Resource[] rs=new PathMatchingResourcePatternResolver().getResources(path);
      factoryBean.setMapperLocations(rs);
      return factoryBean.getObject();
    }

    @Bean(name = "sqlSessionTemplate")
    @Primary
    public SqlSessionTemplate sqlSessionTemplate(@Qualifier("sqlSessionFactory") SqlSessionFactory sqlSessionFactory) throws Exception {
        return new SqlSessionTemplate(sqlSessionFactory);
    }
    
//    
//    @Bean
//    public ProcessEngine processEngine(DataSourceTransactionManager transactionManager, DataSourceProxy dataSourceProxy) throws IOException {
//        SpringProcessEngineConfiguration configuration = new SpringProcessEngineConfiguration();
//        //自动部署已有的流程文件
//        Resource[] resources = new PathMatchingResourcePatternResolver().getResources(ResourceLoader.CLASSPATH_URL_PREFIX + "processes/*.bpmn");
////        configuration.setTransactionManager(transactionManager);
//        configuration.setDataSource(dataSourceProxy);
//        configuration.setDatabaseSchemaUpdate("true");
//        configuration.setDeploymentResources(resources);
//        configuration.setDbIdentityUsed(false);
//        return configuration.buildProcessEngine();
//    }

 
    
    /**
     * 初始化全局事务扫描器
     *
     * @Return: GlobalTransactionScanner
     */

    @Bean
    public GlobalTransactionScanner globalTransactionScanner() {
        GlobalTransactionScanner globalTransactionScanner = new GlobalTransactionScanner("dubbo-activiti", "my_test_tx_group");
        return globalTransactionScanner;
    }
}
 

ActivitiConfig.java

import java.io.IOException;
import javax.annotation.Resource;
import javax.sql.DataSource;
import org.activiti.spring.SpringAsyncExecutor;
import org.activiti.spring.SpringProcessEngineConfiguration;
import org.activiti.spring.boot.AbstractProcessEngineAutoConfiguration;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;

@Configuration//声名为配置类,继承Activiti抽象配置类
public class ActivitiConfig extends AbstractProcessEngineAutoConfiguration {

    @Resource
    DataSource dataSourceProxy;//注入配置好的数据源

    @Resource
    DataSourceTransactionManager transactionManager;//注入配置好的事物管理器

    //注入数据源和事务管理器
    @Bean
    public SpringProcessEngineConfiguration springProcessEngineConfiguration(
        SpringAsyncExecutor springAsyncExecutor) throws IOException {
        return this.baseSpringProcessEngineConfiguration(dataSourceProxy, transactionManager, springAsyncExecutor);
    }
}

 

通过以上修改,fescar可以进行分布式事务控制:

出现 异常后会进行回滚操作

【已解决】SpringBoot集成Fescar0.4.0分布式事务事务不回滚如何解决_第4张图片

 

但是对于activiti的操作还是出现了问题,回滚 操作时出现了不能删除外键关联的数据,导致查询死循环一直报错,有大侠有解决办法的请不吝赐教!!!

具体如下:

【已解决】SpringBoot集成Fescar0.4.0分布式事务事务不回滚如何解决_第5张图片

 

你可能感兴趣的:(Fescar)