Open haoxz11 opened 1 year ago
我也遇到这个问题了
有下文吗
我也遇到了
当前使用版本(必填,否则不予处理)
3.5.2
该问题是如何引起的?(确定最新版也有问题再提!!!)
当调用IService下的saveBatch最终会调用SqlHelper.executeBatch方法,
方法中会调用sqlSession先提交一下
SqlSessionHolder sqlSessionHolder = (SqlSessionHolder) TransactionSynchronizationManager.getResource(sqlSessionFactory); boolean transaction = TransactionSynchronizationManager.isSynchronizationActive(); if (sqlSessionHolder != null) { SqlSession sqlSession = sqlSessionHolder.getSqlSession(); //原生无法支持执行器切换,当存在批量操作时,会嵌套两个session的,优先commit上一个session //按道理来说,这里的值应该一直为false。 sqlSession.commit(!transaction); }
虽然是非强制提交,但是,如果saveBatch上面有insert/update等操作,这个时候如果这个方法体是外包一层事务,那么insert、update会被实际执行;后续如果saveBatch报错啥的,无法回滚;
重现步骤(如果有就写完整)
@Transactional(rollbackFor = Exception.class) public Response<Void> addData(List<Abc> list) { service.save(new Abc()); service.saveBatch(list); throw new Exception(); }
报错信息
这样可以回滚啊。saveBatch 报错,这个sqlSession 的线程会被打上 rollback-only,即使是嵌套事务,内层事务 的saveBatch 异常报给 外层事务,即使外层事务把内层事务的异常给 catch了,当外层事务准备提交的时候 也会因为当前线程的 rollback-only 而报异常
测试代码:
@Service
public class MyService {
@Autowired
private UserService userService;
@Autowired
private ITestService testService;
@Transactional(rollbackFor = Exception.class)
public void addData(List<User> list) throws Exception {
testService.save(new Test(100000));
userService.save(new User("0"));
try {
userService.saveBatch(list);
} catch (Exception e) {
// 此处报Data truncation exception
e.printStackTrace();
}
// throw new Exception();
}
}
@Test
// @Transactional(rollbackFor = Exception.class)
void test2() throws Exception {
List<User> users = List.of(new User("111111111111111111111111111111111111111"), new User("2"), new User("3"), new User("4"), new User("5"));
myService.addData(users);
}
Debug 级别日志:
2024-09-02T15:16:30.226+08:00 DEBUG 23980 --- [demo-21] [ main] o.s.jdbc.support.JdbcTransactionManager : Creating new transaction with name [org.example.service.MyService.addData]: PROPAGATION_REQUIRED,ISOLATION_DEFAULT,-java.lang.Exception
2024-09-02T15:16:30.227+08:00 INFO 23980 --- [demo-21] [ main] com.zaxxer.hikari.HikariDataSource : HikariCorePool - Starting...
2024-09-02T15:16:30.523+08:00 INFO 23980 --- [demo-21] [ main] com.zaxxer.hikari.pool.HikariPool : HikariCorePool - Added connection com.mysql.cj.jdbc.ConnectionImpl@64b20d9c
2024-09-02T15:16:30.524+08:00 INFO 23980 --- [demo-21] [ main] com.zaxxer.hikari.HikariDataSource : HikariCorePool - Start completed.
2024-09-02T15:16:30.529+08:00 DEBUG 23980 --- [demo-21] [ main] o.s.jdbc.support.JdbcTransactionManager : Acquired Connection [HikariProxyConnection@1197981223 wrapping com.mysql.cj.jdbc.ConnectionImpl@64b20d9c] for JDBC transaction
2024-09-02T15:16:30.532+08:00 DEBUG 23980 --- [demo-21] [ main] o.s.jdbc.support.JdbcTransactionManager : Switching JDBC Connection [HikariProxyConnection@1197981223 wrapping com.mysql.cj.jdbc.ConnectionImpl@64b20d9c] to manual commit
Creating a new SqlSession
Registering transaction synchronization for SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@4cd7128]
JDBC Connection [HikariProxyConnection@1197981223 wrapping com.mysql.cj.jdbc.ConnectionImpl@64b20d9c] will be managed by Spring
==> Preparing: INSERT INTO test ( id, a ) VALUES ( ?, ? )
==> Parameters: 1830505061982142465(Long), 100000(Integer)
<== Updates: 1
Releasing transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@4cd7128]
Fetched SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@4cd7128] from current transaction
==> Preparing: INSERT INTO user ( id, user_name, create_time ) VALUES ( ?, ?, ? )
==> Parameters: 1830505062053445634(Long), 0(String), null
<== Updates: 1
Releasing transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@4cd7128]
2024-09-02T15:16:30.606+08:00 DEBUG 23980 --- [demo-21] [ main] o.s.jdbc.support.JdbcTransactionManager : Participating in existing transaction
JDBC Connection [HikariProxyConnection@1197981223 wrapping com.mysql.cj.jdbc.ConnectionImpl@64b20d9c] will be managed by Spring
==> Preparing: INSERT INTO user ( id, user_name, create_time ) VALUES ( ?, ?, ? )
==> Parameters: 1830505062116360194(Long), 111111111111111111111111111111111111111(String), null
==> Parameters: 1830505062116360195(Long), 2(String), null
==> Parameters: 1830505062116360196(Long), 3(String), null
==> Parameters: 1830505062116360197(Long), 4(String), null
==> Parameters: 1830505062116360198(Long), 5(String), null
2024-09-02T15:16:30.710+08:00 DEBUG 23980 --- [demo-21] [ main] o.s.jdbc.support.SQLErrorCodesFactory : Looking up default SQLErrorCodes for DataSource [com.zaxxer.hikari.HikariDataSource@2d527346]
2024-09-02T15:16:30.714+08:00 DEBUG 23980 --- [demo-21] [ main] o.s.jdbc.support.SQLErrorCodesFactory : SQL error codes for 'MySQL' found
2024-09-02T15:16:30.714+08:00 DEBUG 23980 --- [demo-21] [ main] o.s.jdbc.support.SQLErrorCodesFactory : Caching SQL error codes for DataSource [com.zaxxer.hikari.HikariDataSource@2d527346]: database product name is 'MySQL'
2024-09-02T15:16:30.714+08:00 DEBUG 23980 --- [demo-21] [ main] s.j.s.SQLErrorCodeSQLExceptionTranslator : Unable to translate SQLException with Error code '1406', will now try the fallback translator
2024-09-02T15:16:30.715+08:00 DEBUG 23980 --- [demo-21] [ main] o.s.j.s.SQLStateSQLExceptionTranslator : Extracted SQL state class '22' from value '22001'
2024-09-02T15:16:30.715+08:00 DEBUG 23980 --- [demo-21] [ main] o.s.jdbc.support.JdbcTransactionManager : Participating transaction failed - marking existing transaction as rollback-only
2024-09-02T15:16:30.715+08:00 DEBUG 23980 --- [demo-21] [ main] o.s.jdbc.support.JdbcTransactionManager : Setting JDBC transaction [HikariProxyConnection@1197981223 wrapping com.mysql.cj.jdbc.ConnectionImpl@64b20d9c] rollback-only
org.springframework.dao.DataIntegrityViolationException: org.example.dao.UserDao.insert (batch index #1) failed. Cause: java.sql.BatchUpdateException: Data truncation: Data too long for column 'user_name' at row 1
; Data truncation: Data too long for column 'user_name' at row 1
at org.springframework.jdbc.support.SQLStateSQLExceptionTranslator.doTranslate(SQLStateSQLExceptionTranslator.java:118)
at org.springframework.jdbc.support.AbstractFallbackSQLExceptionTranslator.translate(AbstractFallbackSQLExceptionTranslator.java:107)
at org.springframework.jdbc.support.AbstractFallbackSQLExceptionTranslator.translate(AbstractFallbackSQLExceptionTranslator.java:116)
at org.springframework.jdbc.support.AbstractFallbackSQLExceptionTranslator.translate(AbstractFallbackSQLExceptionTranslator.java:116)
at org.mybatis.spring.MyBatisExceptionTranslator.translateExceptionIfPossible(MyBatisExceptionTranslator.java:92)
at com.baomidou.mybatisplus.extension.toolkit.SqlHelper.executeBatch(SqlHelper.java:202)
at com.baomidou.mybatisplus.extension.toolkit.SqlHelper.executeBatch(SqlHelper.java:233)
at com.baomidou.mybatisplus.extension.service.impl.ServiceImpl.executeBatch(ServiceImpl.java:283)
at com.baomidou.mybatisplus.extension.service.impl.ServiceImpl.saveBatch(ServiceImpl.java:178)
at com.baomidou.mybatisplus.extension.service.IService.saveBatch(IService.java:70)
at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:103)
at java.base/java.lang.reflect.Method.invoke(Method.java:580)
at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:354)
at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:196)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:163)
at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:768)
at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:379)
at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:119)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:184)
at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:768)
at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:720)
at org.example.service.impl.UserServiceImpl$$SpringCGLIB$$0.saveBatch(<generated>)
at org.example.service.MyService.addData(MyService.java:24)
at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:103)
at java.base/java.lang.reflect.Method.invoke(Method.java:580)
at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:354)
at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:196)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:163)
at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:768)
at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:379)
at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:119)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:184)
at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:768)
at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:720)
at org.example.service.MyService$$SpringCGLIB$$0.addData(<generated>)
at org.example.Demo.test2(Demo.java:37)
at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:103)
at java.base/java.lang.reflect.Method.invoke(Method.java:580)
at org.junit.platform.commons.util.ReflectionUtils.invokeMethod(ReflectionUtils.java:728)
at org.junit.jupiter.engine.execution.MethodInvocation.proceed(MethodInvocation.java:60)
at org.junit.jupiter.engine.execution.InvocationInterceptorChain$ValidatingInvocation.proceed(InvocationInterceptorChain.java:131)
at org.junit.jupiter.engine.extension.TimeoutExtension.intercept(TimeoutExtension.java:156)
at org.junit.jupiter.engine.extension.TimeoutExtension.interceptTestableMethod(TimeoutExtension.java:147)
at org.junit.jupiter.engine.extension.TimeoutExtension.interceptTestMethod(TimeoutExtension.java:86)
at org.junit.jupiter.engine.execution.InterceptingExecutableInvoker$ReflectiveInterceptorCall.lambda$ofVoidMethod$0(InterceptingExecutableInvoker.java:103)
at org.junit.jupiter.engine.execution.InterceptingExecutableInvoker.lambda$invoke$0(InterceptingExecutableInvoker.java:93)
at org.junit.jupiter.engine.execution.InvocationInterceptorChain$InterceptedInvocation.proceed(InvocationInterceptorChain.java:106)
at org.junit.jupiter.engine.execution.InvocationInterceptorChain.proceed(InvocationInterceptorChain.java:64)
at org.junit.jupiter.engine.execution.InvocationInterceptorChain.chainAndInvoke(InvocationInterceptorChain.java:45)
at org.junit.jupiter.engine.execution.InvocationInterceptorChain.invoke(InvocationInterceptorChain.java:37)
at org.junit.jupiter.engine.execution.InterceptingExecutableInvoker.invoke(InterceptingExecutableInvoker.java:92)
at org.junit.jupiter.engine.execution.InterceptingExecutableInvoker.invoke(InterceptingExecutableInvoker.java:86)
at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.lambda$invokeTestMethod$7(TestMethodTestDescriptor.java:218)
at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.invokeTestMethod(TestMethodTestDescriptor.java:214)
at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.execute(TestMethodTestDescriptor.java:139)
at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.execute(TestMethodTestDescriptor.java:69)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$6(NodeTestTask.java:151)
at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:141)
at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:137)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$9(NodeTestTask.java:139)
at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:138)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:95)
at java.base/java.util.ArrayList.forEach(ArrayList.java:1596)
at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.invokeAll(SameThreadHierarchicalTestExecutorService.java:41)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$6(NodeTestTask.java:155)
at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:141)
at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:137)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$9(NodeTestTask.java:139)
at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:138)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:95)
at java.base/java.util.ArrayList.forEach(ArrayList.java:1596)
at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.invokeAll(SameThreadHierarchicalTestExecutorService.java:41)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$6(NodeTestTask.java:155)
at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:141)
at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:137)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$9(NodeTestTask.java:139)
at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:138)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:95)
at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.submit(SameThreadHierarchicalTestExecutorService.java:35)
at org.junit.platform.engine.support.hierarchical.HierarchicalTestExecutor.execute(HierarchicalTestExecutor.java:57)
at org.junit.platform.engine.support.hierarchical.HierarchicalTestEngine.execute(HierarchicalTestEngine.java:54)
at org.junit.platform.launcher.core.EngineExecutionOrchestrator.execute(EngineExecutionOrchestrator.java:198)
at org.junit.platform.launcher.core.EngineExecutionOrchestrator.execute(EngineExecutionOrchestrator.java:169)
at org.junit.platform.launcher.core.EngineExecutionOrchestrator.execute(EngineExecutionOrchestrator.java:93)
at org.junit.platform.launcher.core.EngineExecutionOrchestrator.lambda$execute$0(EngineExecutionOrchestrator.java:58)
at org.junit.platform.launcher.core.EngineExecutionOrchestrator.withInterceptedStreams(EngineExecutionOrchestrator.java:141)
at org.junit.platform.launcher.core.EngineExecutionOrchestrator.execute(EngineExecutionOrchestrator.java:57)
at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:103)
at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:85)
at org.junit.platform.launcher.core.DelegatingLauncher.execute(DelegatingLauncher.java:47)
at org.junit.platform.launcher.core.SessionPerRequestLauncher.execute(SessionPerRequestLauncher.java:63)
at com.intellij.junit5.JUnit5IdeaTestRunner.startRunnerWithArgs(JUnit5IdeaTestRunner.java:57)
at com.intellij.rt.junit.IdeaTestRunner$Repeater$1.execute(IdeaTestRunner.java:38)
at com.intellij.rt.execution.junit.TestsRepeater.repeat(TestsRepeater.java:11)
at com.intellij.rt.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:35)
at com.intellij.rt.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:232)
at com.intellij.rt.junit.JUnitStarter.main(JUnitStarter.java:55)
Caused by: java.sql.BatchUpdateException: Data truncation: Data too long for column 'user_name' at row 1
at com.mysql.cj.jdbc.exceptions.SQLError.createBatchUpdateException(SQLError.java:224)
at com.mysql.cj.jdbc.ClientPreparedStatement.executeBatchSerially(ClientPreparedStatement.java:816)
at com.mysql.cj.jdbc.ClientPreparedStatement.executeBatchInternal(ClientPreparedStatement.java:418)
at com.mysql.cj.jdbc.StatementImpl.executeBatch(StatementImpl.java:795)
at com.zaxxer.hikari.pool.ProxyStatement.executeBatch(ProxyStatement.java:127)
at com.zaxxer.hikari.pool.HikariProxyPreparedStatement.executeBatch(HikariProxyPreparedStatement.java)
at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:103)
at java.base/java.lang.reflect.Method.invoke(Method.java:580)
at org.apache.ibatis.logging.jdbc.PreparedStatementLogger.invoke(PreparedStatementLogger.java:78)
at jdk.proxy3/jdk.proxy3.$Proxy170.executeBatch(Unknown Source)
at org.apache.ibatis.executor.BatchExecutor.doFlushStatements(BatchExecutor.java:126)
at org.apache.ibatis.executor.BaseExecutor.flushStatements(BaseExecutor.java:129)
at org.apache.ibatis.executor.BaseExecutor.flushStatements(BaseExecutor.java:122)
at org.apache.ibatis.executor.CachingExecutor.flushStatements(CachingExecutor.java:115)
at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:103)
at java.base/java.lang.reflect.Method.invoke(Method.java:580)
at org.apache.ibatis.plugin.Plugin.invoke(Plugin.java:61)
at jdk.proxy2/jdk.proxy2.$Proxy167.flushStatements(Unknown Source)
at org.apache.ibatis.session.defaults.DefaultSqlSession.flushStatements(DefaultSqlSession.java:252)
at com.baomidou.mybatisplus.extension.toolkit.SqlHelper.lambda$executeBatch$1(SqlHelper.java:240)
at com.baomidou.mybatisplus.extension.toolkit.SqlHelper.executeBatch(SqlHelper.java:192)
... 98 more
Caused by: com.mysql.cj.jdbc.exceptions.MysqlDataTruncation: Data truncation: Data too long for column 'user_name' at row 1
at com.mysql.cj.jdbc.exceptions.SQLExceptionsMapping.translateException(SQLExceptionsMapping.java:104)
at com.mysql.cj.jdbc.ClientPreparedStatement.executeInternal(ClientPreparedStatement.java:916)
at com.mysql.cj.jdbc.ClientPreparedStatement.executeUpdateInternal(ClientPreparedStatement.java:1061)
at com.mysql.cj.jdbc.ClientPreparedStatement.executeBatchSerially(ClientPreparedStatement.java:795)
... 117 more
2024-09-02T15:16:30.717+08:00 DEBUG 23980 --- [demo-21] [ main] o.s.jdbc.support.JdbcTransactionManager : Global transaction is marked as rollback-only but transactional code requested commit
Transaction synchronization deregistering SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@4cd7128]
Transaction synchronization closing SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@4cd7128]
2024-09-02T15:16:30.717+08:00 DEBUG 23980 --- [demo-21] [ main] o.s.jdbc.support.JdbcTransactionManager : Initiating transaction rollback
2024-09-02T15:16:30.717+08:00 DEBUG 23980 --- [demo-21] [ main] o.s.jdbc.support.JdbcTransactionManager : Rolling back JDBC transaction on Connection [HikariProxyConnection@1197981223 wrapping com.mysql.cj.jdbc.ConnectionImpl@64b20d9c]
2024-09-02T15:16:30.721+08:00 DEBUG 23980 --- [demo-21] [ main] o.s.jdbc.support.JdbcTransactionManager : Releasing JDBC Connection [HikariProxyConnection@1197981223 wrapping com.mysql.cj.jdbc.ConnectionImpl@64b20d9c] after transaction
org.springframework.transaction.UnexpectedRollbackException: Transaction rolled back because it has been marked as rollback-only
at org.springframework.transaction.support.AbstractPlatformTransactionManager.processRollback(AbstractPlatformTransactionManager.java:938)
at org.springframework.transaction.support.AbstractPlatformTransactionManager.commit(AbstractPlatformTransactionManager.java:754)
at org.springframework.transaction.interceptor.TransactionAspectSupport.commitTransactionAfterReturning(TransactionAspectSupport.java:663)
at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:413)
at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:119)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:184)
at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:768)
at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:720)
at org.example.service.MyService$$SpringCGLIB$$0.addData(<generated>)
at org.example.Demo.test2(Demo.java:37)
at java.base/java.lang.reflect.Method.invoke(Method.java:580)
at java.base/java.util.ArrayList.forEach(ArrayList.java:1596)
at java.base/java.util.ArrayList.forEach(ArrayList.java:1596)
SqlHelper.executeBatch里的sqlSession.commit(!transaction);如果开启事务,并不会做实际提交
我也遇到了,是多数据源的情况,有人解决了吗?
当前使用版本(必填,否则不予处理)
3.5.2
该问题是如何引起的?(确定最新版也有问题再提!!!)
当调用IService下的saveBatch最终会调用SqlHelper.executeBatch方法,
方法中会调用sqlSession先提交一下
虽然是非强制提交,但是,如果saveBatch上面有insert/update等操作,这个时候如果这个方法体是外包一层事务,那么insert、update会被实际执行;后续如果saveBatch报错啥的,无法回滚;
重现步骤(如果有就写完整)
报错信息