apache / shardingsphere

Distributed SQL transaction & query engine for data sharding, scaling, encryption, and more - on any database.
Apache License 2.0
19.87k stars 6.73k forks source link

How to configure 'seata.enable-auto-data-source-proxy' when using shardingsphere? #24586

Closed longkaimao closed 8 months ago

longkaimao commented 1 year ago

version:5.2.0

I am using shardingsphere5.2.0 + Seata1.6.0 for my code,if I configure seata.enable-auto-data-source-proxy=false,and the branch transaction code uses annotation @ShardingSphereTransactionType and @Transactional, then the branch trancaction service report a NullPointException error, which from SeataTransactionHolder.get(). java.lang.NullPointerException: null at org.apache.shardingsphere.transaction.base.seata.at.SeataATShardingTransactionManager.commit(SeataATShardingTransactionManager.java:110) ~

If I configure seata.enable-auto-data-source-proxy=false and the code only used annotation @ShardingSphereTransactionType , or If configure seata.enable-auto-data-source-proxy=true and the code only uses annotation @Transactional. Both the two way everything looks fine.

So,how do I configure it?

thanks!

sandynz commented 1 year ago

Hi @longkaimao , thanks for your feedback. Could you supply a demo project to reproduce it?

sandynz commented 1 year ago

Hi @FlyingZC , could you help to have a look at it?

longkaimao commented 1 year ago

The following is my main code

  1. seata config in bootstrap.yml The property 'enable-auto-data-source-proxy' i is configured at here
sfs:
  nacos:
    server-addr: ${spring.cloud.nacos.discovery.server-addr}
    namespace: seata-server-160
    group: SEATA_GROUP

seata:
  enabled: true
  application-id : ${spring.application.name}
  tx-service-group: default_tx_group
  use-jdk-proxy: true
  enable-auto-data-source-proxy: true
  registry:
    type: nacos
    nacos:
      application: seata-server
      server-addr: ${sfs.nacos.server-addr}
      namespace: ${sfs.nacos.namespace}
      group: ${sfs.nacos.group}
  config:
    type: nacos
    nacos:
      server-addr: ${sfs.nacos.server-addr}
      namespace: ${sfs.nacos.namespace}
      group: ${sfs.nacos.group}
      data-id: seataServer.properties
  service:
    vgroupMapping:
      default_tx_group: default`
  1. sharding config
    
    #账号微服务服务信息-分库又分表
    server.port=9220
    spring.application.name=account
    #订单微服务注册中心
    spring.cloud.nacos.discovery.server-addr=82.157.70.11:8848
    spring.cloud.nacos.discovery.group=DEFAULT_GROUP
    spring.cloud.nacos.discovery.namespace=public
    spring.cloud.nacos.discovery.username=nacos
    spring.cloud.nacos.discovery.password=lkmNacos

sharding-jdbc数据源配置

spring.shardingsphere.datasource.names=ds-0,ds-1 spring.shardingsphere.mode.type=Standalone

spring.shardingsphere.mode.repository.type=File

spring.shardingsphere.mode.overwrite=true spring.shardingsphere.datasource.ds-0.type=com.zaxxer.hikari.HikariDataSource spring.shardingsphere.datasource.ds-0.driver-class-name=com.mysql.cj.jdbc.Driver spring.shardingsphere.datasource.ds-0.jdbc-url=jdbc:mysql://82.157.70.11:3306/seata-account-0?serverTimezone=UTC&characterEncoding=utf8 spring.shardingsphere.datasource.ds-0.username=root spring.shardingsphere.datasource.ds-0.password=l spring.shardingsphere.datasource.ds-1.type=com.zaxxer.hikari.HikariDataSource spring.shardingsphere.datasource.ds-1.driver-class-name=com.mysql.cj.jdbc.Driver spring.shardingsphere.datasource.ds-1.jdbc-url=jdbc:mysql://82.157.70.11:3306/seata-account-1?serverTimezone=UTC&characterEncoding=utf8 spring.shardingsphere.datasource.ds-1.username=root spring.shardingsphere.datasource.ds-1.password=l

sharding-jdbc分片配置

spring.shardingsphere.rules.sharding.default-database-strategy.standard.sharding-column=id spring.shardingsphere.rules.sharding.default-database-strategy.standard.sharding-algorithm-name=database-inline spring.shardingsphere.rules.sharding.binding-tables[0]=t_account

spring.shardingsphere.rules.sharding.broadcast-tables=t_address

spring.shardingsphere.rules.sharding.tables.t_account.actual-data-nodes=ds-$->{0..1}.taccount$->{0..2} spring.shardingsphere.rules.sharding.tables.t_account.table-strategy.standard.sharding-column=id spring.shardingsphere.rules.sharding.tables.t_account.table-strategy.standard.sharding-algorithm-name=t-account-inline

spring.shardingsphere.rules.sharding.tables.t_account.key-generate-strategy.column=id spring.shardingsphere.rules.sharding.tables.t_account.key-generate-strategy.key-generator-name=snowflake

spring.shardingsphere.rules.sharding.sharding-algorithms.database-inline.type=INLINE spring.shardingsphere.rules.sharding.sharding-algorithms.database-inline.props.algorithm-expression=ds-$->{id % 2} spring.shardingsphere.rules.sharding.sharding-algorithms.t-account-inline.type=INLINE spring.shardingsphere.rules.sharding.sharding-algorithms.t-account-inline.props.algorithm-expression=taccount$->{id % 3}

spring.shardingsphere.rules.sharding.key-generators.snowflake.type=SNOWFLAKE

sharding-jdbc显示最终SQL

spring.shardingsphere.props.sql.show=true

mybatis-plus配置

mybatis-plus.configuration.map-underscore-to-camel-case=true logging.level.io.seata=info

  1. branch transaction code

 /**
     * 以下在enable-auto-data-source-proxy开启和关闭的情况下,是否使用注解Transactional和ShardingSphereTransactionType,对事务回滚的结果
     * enable-auto-data-source-proxy     @Transactional    @ShardingSphereTransactionType   结果
     * true                              有                  无                               回滚成功
     * false                             无                  有                               回滚成功
     * false                             有                  无                               分支事务没有回滚
     * false                             有                  有                               空指针异常
     * true                              有                  有                               空指针异常
     * true                              无                  有                               空指针异常
     *
     * @param req
     */
    @Transactional(rollbackFor = Exception.class)
//    @ShardingSphereTransactionType(value = TransactionType.BASE)
    public void op(AccountOpReq req) {
        log.info("Seata全局事务id=================>{}", RootContext.getXID());

        AccountEntity byUserId = new AccountEntity();
        byUserId.setUserId(req.getUserId());
        byUserId.setUsed(new BigDecimal(1000L));
        byUserId.setResidue(req.getMoney());
        this.baseAccountService.save(byUserId);

    }
longkaimao commented 1 year ago

@FlyingZC @sandynz please help me to have a look.Thanks a lot.

longkaimao commented 1 year ago

The NullPointException problem is the same as this issues #22356,but it looks like that issues hasn't been solved yet.

freshchen commented 1 year ago

今天我遇到了类似问题,报错但是不影响回滚,主要是只有开启全局事务的服务(TM)能正常运行,其余的 RM 获取不到就报空指针 解决方式:自己重写下 SeataATShardingSphereTransactionManager 的 commit 和 rollback 方法在 SeataTransactionHolder get 的时候都需要判空后再执行对应的 commit 或者 rollback

github-actions[bot] commented 1 year ago

There hasn't been any activity on this issue recently, and in order to prioritize active issues, it will be marked as stale.

waxJava2615 commented 10 months ago

I have the same problem

linghengqian commented 8 months ago
JsonLYH commented 3 months ago

今天我遇到了类似问题,报错但是不影响回滚,主要是只有开启全局事务的服务(TM)能正常运行,其余的 RM 获取不到就报空指针 解决方式:自己重写下 SeataATShardingSphereTransactionManager 的 commit 和 rollback 方法在 SeataTransactionHolder get 的时候都需要判空后再执行对应的 commit 或者 rollback

我想问下咱重写SeataATShardingSphereTransactionManager哦?有例子嘛?