Skip to content

How to Choose Between Local and Global Transactions with Sharding-JDBC? #7837

@WXingSong

Description

@WXingSong

Check Ahead

  • I have searched the 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?

After integrating Sharding-JDBC with Seata, how can we choose between using local transactions and global transactions based on the requirements?

You can take a look at apache/shardingsphere#37283 roughly.

In summary, when Sharding-JDBC and Seata are used together, all @Transactional annotations are taken over by Seata and executed as global transactions (e.g., writing to undo_log, acquiring locks, etc.). However, in practice, global transactions are only needed for cross-service calls, while transactions within a single service only need to be local. How can I implement this requirement?

I have tried setting Sharding-JDBC to use local transactions and using Seata’s @GlobalTransactional separately for global transactions, but in practice, the following error occurs:

org.springframework.dao.InvalidDataAccessApiUsageException: Error getting generated key or setting result to parameter object. Cause: java.sql.SQLFeatureNotSupportedException: isAfterLast
; isAfterLast
      at org.springframework.jdbc.support.SQLExceptionSubclassTranslator.doTranslate(SQLExceptionSubclassTranslator.java:106)
      at org.springframework.jdbc.support.AbstractFallbackSQLExceptionTranslator.translate(AbstractFallbackSQLExceptionTranslator.java:107)
      at org.springframework.jdbc.support.AbstractFallbackSQLExceptionTranslator.translate(AbstractFallbackSQLExceptionTranslator.java:116)
      at org.mybatis.spring.MyBatisExceptionTranslator.translateExceptionIfPossible(MyBatisExceptionTranslator.java:95)
      at org.mybatis.spring.SqlSessionTemplate$SqlSessionInterceptor.invoke(SqlSessionTemplate.java:347)
      at jdk.proxy2/jdk.proxy2.$Proxy190.insert(Unknown Source)
      at org.mybatis.spring.SqlSessionTemplate.insert(SqlSessionTemplate.java:224)
      at com.baomidou.mybatisplus.core.override.MybatisMapperMethod.execute(MybatisMapperMethod.java:59)
      at com.baomidou.mybatisplus.core.override.MybatisMapperProxy$PlainMethodInvoker.invoke(MybatisMapperProxy.java:156)
      at com.baomidou.mybatisplus.core.override.MybatisMapperProxy.invoke(MybatisMapperProxy.java:93)
      at jdk.proxy2/jdk.proxy2.$Proxy197.insert(Unknown Source)
      at cn.iocoder.yudao.module.humanity.service.TestServiceImpl.test(TestServiceImpl.java:23)
      at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
      at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77)
      at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
      at java.base/java.lang.reflect.Method.invoke(Method.java:568)
      at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:360)
      at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:196)
      at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:163)
      at org.apache.seata.spring.annotation.AdapterInvocationWrapper.proceed(AdapterInvocationWrapper.java:55)
      at org.apache.seata.integration.tx.api.interceptor.handler.GlobalTransactionalInterceptorHandler$2.execute(GlobalTransactionalInterceptorHandler.java:186)
      at org.apache.seata.tm.api.TransactionalTemplate.execute(TransactionalTemplate.java:130)
      at org.apache.seata.integration.tx.api.interceptor.handler.GlobalTransactionalInterceptorHandler.handleGlobalTransaction(GlobalTransactionalInterceptorHandler.java:183)
      at org.apache.seata.integration.tx.api.interceptor.handler.GlobalTransactionalInterceptorHandler.doInvoke(GlobalTransactionalInterceptorHandler.java:155)
      at org.apache.seata.integration.tx.api.interceptor.handler.AbstractProxyInvocationHandler.invoke(AbstractProxyInvocationHandler.java:43)
      at org.apache.seata.spring.annotation.AdapterSpringSeataInterceptor.invoke(AdapterSpringSeataInterceptor.java:44)
      at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:184)
      at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:728)
      at cn.iocoder.yudao.module.humanity.service.TestServiceImpl$$SpringCGLIB$$0.test(<generated>)

How it could be?

No response

Other related information

No response

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions