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]

Reply via email to