beanww opened a new issue, #7686: URL: https://github.com/apache/incubator-seata/issues/7686
### Check Ahead - [x] I have searched the [issues](https://github.com/seata/seata/issues) of this repository and believe that this is not a duplicate. - [ ] I am willing to try to implement this feature myself. ### Why you need it? 背景: postgres14+数据库 seata 2.1 xa模式 1个service内配置了2个数据源 所有数据源在启动时做了proxy 问题: 如果service的方法上注解了2个事务注解 @GlobalTransactional @Transactional public void doSth(){ .. } 那么 doSth里面如果通过@DS注解切换数据源,是无效的 如果不加@Transactional注解,即: @GlobalTransactional public void doSth(){ .. } 那么doSth里面@DS注解是有效的,可以切换数据源, 但是,不加@Transactional注解时,会导致service里每一个sql语句都会生成一个seata分支事务 ,从pg的pending事务表:pg_prepared_xacts,也可以看出来,因此这种方式切换数据源对数据库要求过高,似乎没法使用 建议: 是否有一种机制,可以在seata事务内加上@Transactional事务注解的情况也支持多数据源切换? 或者,不加@Transactional注解时,seata可以实现不要让一个service内所有的sql都各自生成一个分支事务,而是判断如果使用的是相同的数据源时,使用同一个分支事务? ### How it could be? config: `seata: data-source-proxy-mode: XA enable-auto-data-source-proxy: false enabled: true` 自己写的proxy数据源处理类: `@Configuration @ConditionalOnExpression("${seata.enabled:false} && '${seata.data-source-proxy-mode:}'.equalsIgnoreCase('XA')") public class XaDynamicDataSourceConfig { @Autowired private DynamicDataSourceProperties dynamicDataSourceProperties; @Bean public DynamicDataSourceProvider dynamicDataSourceProvider() { // 从 YAML 里获取所有数据源的配置 Map<String, DataSourceProperty> dataSourcePropertiesMap = dynamicDataSourceProperties.getDatasource(); // 全局 Druid 配置 DruidConfig globalDruidConfig = dynamicDataSourceProperties.getDruid(); return () -> { Map<String, DataSource> dataSourceMap = new HashMap<>(); // 遍历所有数据源,创建 XA 代理数据源 for (Map.Entry<String, DataSourceProperty> entry : dataSourcePropertiesMap.entrySet()) { String dsKey = entry.getKey(); DataSourceProperty dsProp = entry.getValue(); // 包含 URL、用户名、密码 // 1. 创建 DruidXADataSource DruidXADataSource druidXADataSource = new DruidXADataSource(); // 2. 手动注入连接信息(从 YAML 加载) druidXADataSource.setUrl(dsProp.getUrl()); druidXADataSource.setUsername(dsProp.getUsername()); druidXADataSource.setPassword(dsProp.getPassword()); druidXADataSource.setDriverClassName(dsProp.getDriverClassName()); // 3. 注入全局 Druid 配置(initial-size、min-idle 等) configureDruid(druidXADataSource, globalDruidConfig); // 4. Seata XA 代理 DataSourceProxyXA proxyXA = new DataSourceProxyXA(druidXADataSource, dsKey); // 5. 加入数据源 Map dataSourceMap.put(dsKey, proxyXA); } return dataSourceMap; }; }` ### Other related information _No response_ -- This is an automated message from the Apache Git Service. To respond to the message, please log on to GitHub and use the URL above to go to the specific comment. To unsubscribe, e-mail: [email protected] For queries about this service, please contact Infrastructure at: [email protected] --------------------------------------------------------------------- To unsubscribe, e-mail: [email protected] For additional commands, e-mail: [email protected]
