参考的文章:
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中好像一直没有存入数据
通过断点,数据源已经注入进来了
下面的sqlSessionFactory方法没有执行,不知是否有影响
============================问题原因============解决办法===================================
问题原因:
没有注意到工程中已经有一个数据源的配置类DataSourceConfig,导致FescarConfig没有起作用
解决办法:
将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.add(wallFilter);
((DruidDataSource)ds).setProxyFilters(filters);
return ds;
// DataSource dataSource=DataSourceBuilder.create().type(DruidDataSource.class).build();
// List
// 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可以进行分布式事务控制:
出现 异常后会进行回滚操作
但是对于activiti的操作还是出现了问题,回滚 操作时出现了不能删除外键关联的数据,导致查询死循环一直报错,有大侠有解决办法的请不吝赐教!!!
具体如下: