繁体   English   中英

JDBC 中的 Spring Boot:@Transactional 不适用于 MSSQL Server 中的多个表

[英]Spring Boot in JDBC: @Transactional is not working for multiple tables in MSSQL Server

更新多个表时,我试图让 @Transactional 在 Spring Boot 中工作。 此代码不会因错误而回滚。 我怎样才能解决这个问题? 我运行了表 1 和表 2 有效而表 3 失败的测试用例。 它应该回滚所有 1、2、3。代码中是否缺少任何其他语法或注释?

想知道它是否有这个问题: Does using spring JdbcTemplate 创建到 sql server 的新连接?

尝试 1:

@Transactional
public void createData() {
    updateTable1();
    updateTable2();
    updateTable3();
}

private updateTable1() {
    namedParameterJdbcTemplate.batchUpdate(TABLE1_INSERT_STRING, parameters1);
}

private updateTable2() {
    namedParameterJdbcTemplate.batchUpdate(TABLE2_INSERT_STRING, parameters2);
}

private updateTable3() {
    namedParameterJdbcTemplate.batchUpdate(TABLE3_INSERT_STRING, parameters3);
}

应用程序有@EnableTransactionManagement:

@EnableTransactionManagement
public class Application extends SpringBootServletInitializer {
    public static void main(String[] args) {
      

尝试 1 记录:

===================================
2021-10-11 19:17:58 DEBUG 
TraceId:  
CustomerId: 
CLASS: org.springframework.jdbc.datasource.DataSourceUtils
Fetching JDBC Connection from DataSource

===================================
2021-10-11 19:17:59 DEBUG 
TraceId: 151f53360d2b4668 
CustomerId: 
CLASS: org.springframework.jdbc.support.JdbcTransactionManager
Creating new transaction with name [com.abccompany.services.service.charge.capture.server.repository.sql.EncounterRepository.createEncounter]: PROPAGATION_REQUIRED,ISOLATION_DEFAULT
   
===================================
2021-10-11 19:17:59 TRACE 
TraceId: 151f53360d2b4668 
CustomerId: 
CLASS: org.springframework.transaction.interceptor.TransactionInterceptor
Getting transaction for [com.abccompany.services.service.charge.capture.server.repository.sql.EncounterRepository.createEncounter]

===================================
2021-10-11 19:17:59 DEBUG 
TraceId: 151f53360d2b4668 
CustomerId: 
CLASS: org.springframework.jdbc.core.JdbcTemplate
Executing SQL update and returning generated keys

===================================
2021-10-11 19:17:59 DEBUG 
TraceId: 151f53360d2b4668 
CustomerId: 
CLASS: org.springframework.jdbc.core.JdbcTemplate
Executing prepared SQL statement [INSERT INTO dbo.Encounter(PracticeID, PatientID, DoctorID, AppointmentID, LocationID, Notes, EncounterStatusID, AdminNotes, AmountPaid, CreatedUserID, PlaceOfServiceCode, PostingDate, PatientCaseID, DateOfService, DateOfServiceTo, SupervisingProviderID, EncounterGuid, ClaimTypeID, EncounterMode, DoNotSendElectronic, DoNotSendElectronicSecondary, overrideClosingDate, ReferringPhysicianID) VALUES ( ?, ? , ?,?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ISNULL(?,newid()), ?, ?, ?, ?, ?, ?)]

===================================
2021-10-11 19:17:59 DEBUG 
TraceId: 151f53360d2b4668 
CustomerId: 
CLASS: org.springframework.jdbc.datasource.DataSourceUtils
Fetching JDBC Connection from DataSource

===================================
2021-10-11 19:18:00 DEBUG 
TraceId: 151f53360d2b4668 
CustomerId: 
CLASS: org.springframework.jdbc.support.SQLErrorCodesFactory
Looking up default SQLErrorCodes for DataSource [com.kareo.library.servercore.data.pm.PMDataSourceFactory$PMDataSource@2a02c45a]

===================================
2021-10-11 19:18:00 DEBUG 
TraceId: 151f53360d2b4668 
CustomerId: 
CLASS: org.springframework.jdbc.support.SQLErrorCodesFactory
SQL error codes for 'Microsoft SQL Server' found

===================================
2021-10-11 19:18:00 DEBUG 
TraceId: 151f53360d2b4668 
CustomerId: 
CLASS: org.springframework.jdbc.support.SQLErrorCodesFactory
Caching SQL error codes for DataSource [com.kareo.library.servercore.data.pm.PMDataSourceFactory$PMDataSource@2a02c45a]: database product name is 'Microsoft SQL Server'

===================================
2021-10-11 19:18:00 DEBUG 
TraceId: 151f53360d2b4668 
CustomerId: 
CLASS: org.springframework.jdbc.support.SQLErrorCodeSQLExceptionTranslator
Unable to translate SQLException with Error code '8152', will now try the fallback translator

===================================
2021-10-11 19:18:00 DEBUG 
TraceId: 151f53360d2b4668 
CustomerId: 
CLASS: org.springframework.jdbc.support.SQLStateSQLExceptionTranslator
Extracted SQL state class '22' from value '22001'

===================================
2021-10-11 19:18:00 TRACE 
TraceId: 151f53360d2b4668 
CustomerId: 
CLASS: org.springframework.transaction.interceptor.TransactionInterceptor
Completing transaction for [com.kareo.services.service.charge.capture.server.repository.sql.EncounterRepository.createEncounter] after exception: org.springframework.dao.DataIntegrityViolationException: PreparedStatementCallback; SQL [INSERT INTO dbo.EncounterProcedure(EncounterID, ProcedureCodeDictionaryID, ServiceChargeAmount, AnesthesiaTime, ServiceUnitCount, ProcedureModifier1, ProcedureModifier2, ProcedureModifier3, ProcedureModifier4, ServiceEndDate, ProcedureDateOfService, PracticeID) VALUES (?, ? , ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)]; Data truncation; nested exception is java.sql.BatchUpdateException: Data truncation

===================================
2021-10-11 19:18:00 TRACE 
TraceId: 151f53360d2b4668 
CustomerId: 
CLASS: org.springframework.transaction.interceptor.RuleBasedTransactionAttribute
Applying rules to determine whether transaction should rollback on org.springframework.dao.DataIntegrityViolationException: PreparedStatementCallback; SQL [INSERT INTO dbo.EncounterProcedure(EncounterID, ProcedureCodeDictionaryID, ServiceChargeAmount, AnesthesiaTime, ServiceUnitCount, ProcedureModifier1, ProcedureModifier2, ProcedureModifier3, ProcedureModifier4, ServiceEndDate, ProcedureDateOfService, PracticeID) VALUES (?, ? , ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)]; Data truncation; nested exception is java.sql.BatchUpdateException: Data truncation

===================================
2021-10-11 19:18:00 TRACE 
TraceId: 151f53360d2b4668 
CustomerId: 
CLASS: org.springframework.transaction.interceptor.RuleBasedTransactionAttribute
Winning rollback rule is: null

===================================
2021-10-11 19:18:00 TRACE 
TraceId: 151f53360d2b4668 
CustomerId: 
CLASS: org.springframework.transaction.interceptor.RuleBasedTransactionAttribute
No relevant rollback rule found: applying default rules

===================================
2021-10-11 19:18:00 DEBUG 
TraceId: 151f53360d2b4668 
CustomerId: 
CLASS: org.springframework.jdbc.support.JdbcTransactionManager
Initiating transaction rollback

在此处输入图片说明

尝试 2:

private TransactionTemplate transactionTemplate;

public TestRepository(PlatformTransactionManager transactionManager) {
     this.transactionTemplate = new TransactionTemplate(transactionManager);
}

public void createData() {
    transactionTemplate.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRES_NEW);
    transactionTemplate.execute(status -> {
        updateTable1();
        updateTable2();
        updateTable3();
    } catch (Exception exception) {
         exception.printStackTrace();
         status.setRollbackOnly();
         throw new RuntimeException(exception);
    }

尝试 2 记录:

===================================
2021-10-11 17:36:54 TRACE 
TraceId: bba0ffd336161184 
CustomerId: 
CLASS: org.springframework.transaction.interceptor.TransactionInterceptor
Completing transaction for [com.abccompany.services.service.charge.capture.server.facade.EncounterFacade.createEncounter] after exception: java.lang.RuntimeException: org.springframework.dao.DataIntegrityViolationException: PreparedStatementCallback; SQL [INSERT INTO dbo.EncounterProcedure(EncounterID, ProcedureCodeDictionaryID, ServiceChargeAmount, AnesthesiaTime, ServiceUnitCount, ProcedureModifier1, ProcedureModifier2, ProcedureModifier3, ProcedureModifier4, ServiceEndDate, ProcedureDateOfService, PracticeID) VALUES (?, ? , ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)]; Data truncation; nested exception is java.sql.BatchUpdateException: Data truncation

===================================
2021-10-11 17:36:54 TRACE 
TraceId: bba0ffd336161184 
CustomerId: 
CLASS: org.springframework.transaction.interceptor.RuleBasedTransactionAttribute
Applying rules to determine whether transaction should rollback on java.lang.RuntimeException: org.springframework.dao.DataIntegrityViolationException: PreparedStatementCallback; SQL [INSERT INTO dbo.EncounterProcedure(EncounterID, ProcedureCodeDictionaryID, ServiceChargeAmount, AnesthesiaTime, ServiceUnitCount, ProcedureModifier1, ProcedureModifier2, ProcedureModifier3, ProcedureModifier4, ServiceEndDate, ProcedureDateOfService, PracticeID) VALUES (?, ? , ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)]; Data truncation; nested exception is java.sql.BatchUpdateException: Data truncation

===================================
2021-10-11 17:36:54 TRACE 
TraceId: bba0ffd336161184 
CustomerId: 
CLASS: org.springframework.transaction.interceptor.RuleBasedTransactionAttribute
Winning rollback rule is: null

===================================
2021-10-11 17:36:54 TRACE 
TraceId: bba0ffd336161184 
CustomerId: 
CLASS: org.springframework.transaction.interceptor.RuleBasedTransactionAttribute
No relevant rollback rule found: applying default rules

完整日志

===================================
2021-10-14 17:57:54 TRACE 
TraceId: 7dc1bb4dd4fca9ed 
CustomerId: 
CLASS: org.springframework.transaction.interceptor.TransactionInterceptor
Getting transaction for [com.abccompany.services.service.charge.capture.server.facade.EncounterFacade.createEncounter]

===================================
2021-10-14 17:57:54 TRACE 
TraceId: 7dc1bb4dd4fca9ed 
CustomerId: 
CLASS: org.springframework.transaction.interceptor.TransactionInterceptor
Getting transaction for [com.abccompany.services.service.charge.capture.server.repository.sql.EncounterRepository.createEncounter]

===================================
2021-10-14 17:57:55 TRACE 
TraceId: 7dc1bb4dd4fca9ed 
CustomerId: 
CLASS: org.springframework.transaction.interceptor.TransactionInterceptor
Completing transaction for [com.abccompany.services.service.charge.capture.server.repository.sql.EncounterRepository.createEncounter] after exception: org.springframework.dao.DataIntegrityViolationException: PreparedStatementCallback; SQL [INSERT INTO dbo.EncounterProcedure(EncounterID, ProcedureCodeDictionaryID, ServiceChargeAmount, AnesthesiaTime, ServiceUnitCount, ProcedureModifier1, ProcedureModifier2, ProcedureModifier3, ProcedureModifier4, ServiceEndDate, ProcedureDateOfService, PracticeID, EncounterDiagnosisID1, EncounterDiagnosisID2, EncounterDiagnosisID3, EncounterDiagnosisID4, EncounterDiagnosisID5, EncounterDiagnosisID6, EncounterDiagnosisID7, EncounterDiagnosisID8) VALUES (?, ? , ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?,?, ?, ?, ?, ?)]; Data truncation; nested exception is java.sql.BatchUpdateException: Data truncation

===================================
2021-10-14 17:57:55 TRACE 
TraceId: 7dc1bb4dd4fca9ed 
CustomerId: 
CLASS: org.springframework.transaction.interceptor.RuleBasedTransactionAttribute
Applying rules to determine whether transaction should rollback on org.springframework.dao.DataIntegrityViolationException: PreparedStatementCallback; SQL [INSERT INTO dbo.EncounterProcedure(EncounterID, ProcedureCodeDictionaryID, ServiceChargeAmount, AnesthesiaTime, ServiceUnitCount, ProcedureModifier1, ProcedureModifier2, ProcedureModifier3, ProcedureModifier4, ServiceEndDate, ProcedureDateOfService, PracticeID, EncounterDiagnosisID1, EncounterDiagnosisID2, EncounterDiagnosisID3, EncounterDiagnosisID4, EncounterDiagnosisID5, EncounterDiagnosisID6, EncounterDiagnosisID7, EncounterDiagnosisID8) VALUES (?, ? , ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?,?, ?, ?, ?, ?)]; Data truncation; nested exception is java.sql.BatchUpdateException: Data truncation

===================================
2021-10-14 17:57:55 TRACE 
TraceId: 7dc1bb4dd4fca9ed 
CustomerId: 
CLASS: org.springframework.transaction.interceptor.RuleBasedTransactionAttribute
Winning rollback rule is: null

===================================
2021-10-14 17:57:55 TRACE 
TraceId: 7dc1bb4dd4fca9ed 
CustomerId: 
CLASS: org.springframework.transaction.interceptor.RuleBasedTransactionAttribute
No relevant rollback rule found: applying default rules

===================================
2021-10-14 17:57:55 TRACE 
TraceId: 7dc1bb4dd4fca9ed 
CustomerId: 
CLASS: org.springframework.transaction.interceptor.TransactionInterceptor
Completing transaction for [com.abccompany.services.service.charge.capture.server.facade.EncounterFacade.createEncounter] after exception: org.springframework.dao.DataIntegrityViolationException: PreparedStatementCallback; SQL [INSERT INTO dbo.EncounterProcedure(EncounterID, ProcedureCodeDictionaryID, ServiceChargeAmount, AnesthesiaTime, ServiceUnitCount, ProcedureModifier1, ProcedureModifier2, ProcedureModifier3, ProcedureModifier4, ServiceEndDate, ProcedureDateOfService, PracticeID, EncounterDiagnosisID1, EncounterDiagnosisID2, EncounterDiagnosisID3, EncounterDiagnosisID4, EncounterDiagnosisID5, EncounterDiagnosisID6, EncounterDiagnosisID7, EncounterDiagnosisID8) VALUES (?, ? , ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?,?, ?, ?, ?, ?)]; Data truncation; nested exception is java.sql.BatchUpdateException: Data truncation

===================================
2021-10-14 17:57:55 TRACE 
TraceId: 7dc1bb4dd4fca9ed 
CustomerId: 
CLASS: org.springframework.transaction.interceptor.RuleBasedTransactionAttribute
Applying rules to determine whether transaction should rollback on org.springframework.dao.DataIntegrityViolationException: PreparedStatementCallback; SQL [INSERT INTO dbo.EncounterProcedure(EncounterID, ProcedureCodeDictionaryID, ServiceChargeAmount, AnesthesiaTime, ServiceUnitCount, ProcedureModifier1, ProcedureModifier2, ProcedureModifier3, ProcedureModifier4, ServiceEndDate, ProcedureDateOfService, PracticeID, EncounterDiagnosisID1, EncounterDiagnosisID2, EncounterDiagnosisID3, EncounterDiagnosisID4, EncounterDiagnosisID5, EncounterDiagnosisID6, EncounterDiagnosisID7, EncounterDiagnosisID8) VALUES (?, ? , ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?,?, ?, ?, ?, ?)]; Data truncation; nested exception is java.sql.BatchUpdateException: Data truncation

===================================
2021-10-14 17:57:55 TRACE 
TraceId: 7dc1bb4dd4fca9ed 
CustomerId: 
CLASS: org.springframework.transaction.interceptor.RuleBasedTransactionAttribute
Winning rollback rule is: null

===================================
2021-10-14 17:57:55 TRACE 
TraceId: 7dc1bb4dd4fca9ed 
CustomerId: 
CLASS: org.springframework.transaction.interceptor.RuleBasedTransactionAttribute
No relevant rollback rule found: applying default rules

===================================
2021-10-14 17:57:55 ERROR 
TraceId: 7dc1bb4dd4fca9ed 
CustomerId: 
CLASS: errorLogger
Message: PreparedStatementCallback; SQL [INSERT INTO dbo.EncounterProcedure(EncounterID, ProcedureCodeDictionaryID, ServiceChargeAmount, AnesthesiaTime, ServiceUnitCount, ProcedureModifier1, ProcedureModifier2, ProcedureModifier3, ProcedureModifier4, ServiceEndDate, ProcedureDateOfService, PracticeID, EncounterDiagnosisID1, EncounterDiagnosisID2, EncounterDiagnosisID3, EncounterDiagnosisID4, EncounterDiagnosisID5, EncounterDiagnosisID6, EncounterDiagnosisID7, EncounterDiagnosisID8) VALUES (?, ? , ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?,?, ?, ?, ?, ?)]; Data truncation; nested exception is java.sql.BatchUpdateException: Data truncation
ErrorUUID: f538fc46-984b-4e55-bb10-f592466970b9
ErrorCode: 500
ErrorType: DataIntegrityViolationException
ServicesStack: charge-capture-service
ServiceName: charge-capture-service
Host: KMAC-15SJGH5
StackTrace: org.springframework.dao.DataIntegrityViolationException: PreparedStatementCallback; SQL [INSERT INTO dbo.EncounterProcedure(EncounterID, ProcedureCodeDictionaryID, ServiceChargeAmount, AnesthesiaTime, ServiceUnitCount, ProcedureModifier1, ProcedureModifier2, ProcedureModifier3, ProcedureModifier4, ServiceEndDate, ProcedureDateOfService, PracticeID, EncounterDiagnosisID1, EncounterDiagnosisID2, EncounterDiagnosisID3, EncounterDiagnosisID4, EncounterDiagnosisID5, EncounterDiagnosisID6, EncounterDiagnosisID7, EncounterDiagnosisID8) VALUES (?, ? , ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?,?, ?, ?, ?, ?)]; Data truncation; nested exception is java.sql.BatchUpdateException: Data truncation
    at org.springframework.jdbc.support.SQLStateSQLExceptionTranslator.doTranslate(SQLStateSQLExceptionTranslator.java:104)
    at org.springframework.jdbc.support.AbstractFallbackSQLExceptionTranslator.translate(AbstractFallbackSQLExceptionTranslator.java:70)
    at org.springframework.jdbc.support.AbstractFallbackSQLExceptionTranslator.translate(AbstractFallbackSQLExceptionTranslator.java:79)
    at org.springframework.jdbc.support.AbstractFallbackSQLExceptionTranslator.translate(AbstractFallbackSQLExceptionTranslator.java:79)
    at org.springframework.jdbc.core.JdbcTemplate.translateException(JdbcTemplate.java:1541)
    at org.springframework.jdbc.core.JdbcTemplate.execute(JdbcTemplate.java:667)
    at org.springframework.jdbc.core.JdbcTemplate.execute(JdbcTemplate.java:691)
    at org.springframework.jdbc.core.JdbcTemplate.batchUpdate(JdbcTemplate.java:1034)
    at org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate.batchUpdate(NamedParameterJdbcTemplate.java:373)
    at com.abccompany.library.servercore.data.StatisticsGatheringNamedParameterJdbcTemplate.access$801(StatisticsGatheringNamedParameterJdbcTemplate.java:25)
    at com.abccompany.library.servercore.data.StatisticsGatheringNamedParameterJdbcTemplate$9.call(StatisticsGatheringNamedParameterJdbcTemplate.java:173)
    at com.abccompany.library.servercore.data.StatisticsGatheringNamedParameterJdbcTemplate$9.call(StatisticsGatheringNamedParameterJdbcTemplate.java:170)
    at com.abccompany.library.servercore.data.StatisticsGatheringNamedParameterJdbcTemplate.recordExecutionTime(StatisticsGatheringNamedParameterJdbcTemplate.java:188)
    at com.abccompany.library.servercore.data.StatisticsGatheringNamedParameterJdbcTemplate.batchUpdate(StatisticsGatheringNamedParameterJdbcTemplate.java:170)
    at com.abccompany.services.service.charge.capture.server.repository.sql.EncounterRepository.createEncounter(EncounterRepository.java:325)
    at com.abccompany.services.service.charge.capture.server.repository.sql.EncounterRepository$$FastClassBySpringCGLIB$$dfd7e0f6.invoke(<generated>)
    at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:218)
    at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:779)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:163)
    at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:750)
    at org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.java:137)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
    at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:750)
    at org.springframework.transaction.interceptor.TransactionInterceptor$1.proceedWithInvocation(TransactionInterceptor.java:123)
    at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:388)
    at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:119)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
    at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:750)
    at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:692)
    at com.abccompany.services.service.charge.capture.server.repository.sql.EncounterRepository$$EnhancerBySpringCGLIB$$59b88173.createEncounter(<generated>)
    at com.abccompany.services.service.charge.capture.server.facade.EncounterFacade.createEncounter(EncounterFacade.java:65)
    at com.abccompany.services.service.charge.capture.server.facade.EncounterFacade$$FastClassBySpringCGLIB$$23023cb6.invoke(<generated>)
    at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:218)
    at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:779)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:163)
    at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:750)
    at org.springframework.transaction.interceptor.TransactionInterceptor$1.proceedWithInvocation(TransactionInterceptor.java:123)
    at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:388)
    at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:119)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
    at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:750)
    at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:692)
    at com.abccompany.services.service.charge.capture.server.facade.EncounterFacade$$EnhancerBySpringCGLIB$$6baeecb3.createEncounter(<generated>)
    at com.abccompany.services.service.charge.capture.server.controller.EncounterController.createEncounter(EncounterController.java:35)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:497)
    at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:197)
    at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:141)
    at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:106)
    at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:894)
    at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:808)
    at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:87)
    at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1060)
    at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:962)
    at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1006)
    at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:909)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:652)
    at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:883)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:733)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:227)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)
    at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:53)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)
    at com.abccompany.library.springboot.starter.abccompanytrace.abccompanyTracerFilter.doFilterInternal(abccompanyTracerFilter.java:45)
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)
    at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:100)
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)
    at org.springframework.web.filter.FormContentFilter.doFilterInternal(FormContentFilter.java:93)
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)
    at org.springframework.boot.actuate.metrics.web.servlet.WebMvcMetricsFilter.doFilterInternal(WebMvcMetricsFilter.java:93)
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)
    at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:201)
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:202)
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:97)
    at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:542)
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:143)
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:92)
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:78)
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:346)
    at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:374)
    at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:65)
    at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:887)
    at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1684)
    at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
    at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
    at java.lang.Thread.run(Thread.java:745)
Caused by: java.sql.BatchUpdateException: Data truncation
    at net.sourceforge.jtds.jdbc.JtdsStatement.executeBatch(JtdsStatement.java:1069)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:497)
    at org.apache.tomcat.jdbc.pool.StatementFacade$StatementProxy.invoke(StatementFacade.java:114)
    at com.sun.proxy.$Proxy204.executeBatch(Unknown Source)
    at org.springframework.jdbc.core.JdbcTemplate.lambda$batchUpdate$4(JdbcTemplate.java:1048)
    at org.springframework.jdbc.core.JdbcTemplate.execute(JdbcTemplate.java:651)
    

它应该根据您发布的代码工作。

您可以检查几件事以进行进一步的故障排除:

  1. 确保您使用的是org.springframework包中的@Transactional而不是javax.transaction包中的

  2. 打开并配置以下记录器以获得更详细的日志记录以查看是否有任何见解:

    • org.springframework.transaction.interceptor到 TRACE 级别
    • org.springframework.transaction.support到 DEBUG 级别

注意事务方法抛出异常后是否会调用TransactionInterceptor#completeTransactionAfterThrowing() 应该调用它来正常处理回滚。

还要注意查看是否有一些日志说在事务方法返回之前提交事务。 如果是,那么出了点问题。

如果您仍在苦苦挣扎,请向我展示记录的内容。

我尝试在带有 Spring Boot 和内存数据库 h2 的简单命令行程序上使用 jdbctemplate 测试事务行为 - 它似乎按预期工作。 这是我的代码

ManagingTransactionsApplication



@SpringBootApplication
public class ManagingTransactionsApplication {

    public static void main(String[] args) {
        SpringApplication.run(ManagingTransactionsApplication.class, args);
    }

}


TransactionTestService


@Component
public class TransactionTestService {

    private final static Logger logger = LoggerFactory.getLogger(TransactionTestService.class);

    private final NamedParameterJdbcTemplate jdbcTemplate;

    public TransactionTestService(NamedParameterJdbcTemplate jdbcTemplate) {
        this.jdbcTemplate = jdbcTemplate;
    }

    @Transactional
    public void bookInTransaction(String... persons) {
        insertInTable1(persons[0]);
        insertInTable2(persons[1]);
        insertInTable3(persons[2]);
    }

    public void insertInTable1(String person) {
        logger.info("Booking " + person + " in a seat...");
        Map<String, String> map = new HashMap<String, String>();
        map.put("FIRST_NAME", person);
        jdbcTemplate.update("insert into TABLE1(FIRST_NAME) values (:FIRST_NAME)", map);
    }

    public void insertInTable2(String person) {
        logger.info("Booking " + person + " in a seat...");
        Map<String, String> map = new HashMap<String, String>();
        map.put("FIRST_NAME", person);
        jdbcTemplate.update("insert into TABLE2(FIRST_NAME) values (:FIRST_NAME)", map);
    }

    public void insertInTable3(String person) {
        logger.info("Booking " + person + " in a seat...");
        Map<String, String> map = new HashMap<String, String>();
        map.put("FIRST_NAME", person);
        jdbcTemplate.update("insert into TABLE3(FIRST_NAME) values (:FIRST_NAME)", map);
    }

    public List<String> findAllBookings() {
        return jdbcTemplate.query("select FIRST_NAME from BOOKINGS", (rs, rowNum) -> rs.getString("FIRST_NAME"));
    }

}

应用程序运行器

@Component
class AppRunner implements CommandLineRunner {

    private final static Logger logger = LoggerFactory.getLogger(AppRunner.class);
    private final TransactionTestService transTestService;

    public AppRunner(BookingService bookingService, TransactionTestService transTestService) {
        this.transTestService = transTestService;
    }

    @Override
    public void run(String... args) throws Exception {

        try {
            transTestService.bookInTransaction("Alice", "Bob", "Shailendra");
        } catch (RuntimeException e) {
            logger.info("--- The following exception is expect because 'Shailendra' is too " + "big for the DB ---v");
            logger.error(e.getMessage());
        }

        for (String person : transTestService.findAllBookings()) {
            logger.info("So far, " + person + " is booked.");
        }

    }

}


schema.sql

drop table TABLE1 if exists;
create table TABLE1(ID serial, FIRST_NAME varchar(5) NOT NULL);

drop table TABLE2 if exists;
create table TABLE2(ID serial, FIRST_NAME varchar(5) NOT NULL);

drop table TABLE3 if exists;
create table TABLE3(ID serial, FIRST_NAME varchar(5) NOT NULL);

基本上我会做 3 次插入——最后一次插入时,值将超过 5 的最大长度,因此插入将失败,整个事务也应该失败,并且在查询数据时,它应该导致没有记录保存。 我在控制台上得到以下信息,但未找到数据库中的数据

2021-10-11 15:00:21.726  INFO 23860 --- [           main] c.e.m.TransactionTestService             : Booking Alice in a seat...
2021-10-11 15:00:21.746  INFO 23860 --- [           main] c.e.m.TransactionTestService             : Booking Bob in a seat...
2021-10-11 15:00:21.746  INFO 23860 --- [           main] c.e.m.TransactionTestService             : Booking Shailendra in a seat...
2021-10-11 15:00:21.909  INFO 23860 --- [           main] c.e.managingtransactions.AppRunner       : --- The following exception is expect because 'Shailendra' is too big for the DB ---v
2021-10-11 15:00:21.909 ERROR 23860 --- [           main] c.e.managingtransactions.AppRunner       : PreparedStatementCallback; SQL [insert into TABLE1(FIRST_NAME) values (?)]; Value too long for column "FIRST_NAME VARCHAR(5)": "'Shailendra' (10)"; SQL statement:
insert into TABLE1(FIRST_NAME) values (?) [22001-200]; nested exception is org.h2.jdbc.JdbcSQLDataException: Value too long for column "FIRST_NAME VARCHAR(5)": "'Shailendra' (10)"; SQL statement:
insert into TABLE1(FIRST_NAME) values (?) [22001-200]

在下面为事务添加调试/跟踪是有关 Spring 管理的事务的更详细信息,并提到它回滚事务的事实

2021-10-11 15:22:22.734  INFO 23124 --- [           main] c.e.m.ManagingTransactionsApplication    : Started ManagingTransactionsApplication in 5.369 seconds (JVM running for 6.179)
2021-10-11 15:22:22.734 TRACE 23124 --- [           main] o.s.t.i.TransactionInterceptor           : Getting transaction for [com.example.managingtransactions.TransactionTestService.bookInTransaction]
2021-10-11 15:22:22.765  INFO 23124 --- [           main] c.e.m.TransactionTestService             : Booking Alice in a seat...
2021-10-11 15:22:22.787  INFO 23124 --- [           main] c.e.m.TransactionTestService             : Booking Bob in a seat...
2021-10-11 15:22:22.787  INFO 23124 --- [           main] c.e.m.TransactionTestService             : Booking Shailendra in a seat...
2021-10-11 15:22:22.939 TRACE 23124 --- [           main] o.s.t.i.TransactionInterceptor           : Completing transaction for [com.example.managingtransactions.TransactionTestService.bookInTransaction] after exception: org.springframework.dao.DataIntegrityViolationException: PreparedStatementCallback; SQL [insert into TABLE1(FIRST_NAME) values (?)]; Value too long for column "FIRST_NAME VARCHAR(5)": "'Shailendra' (10)"; SQL statement:
insert into TABLE1(FIRST_NAME) values (?) [22001-200]; nested exception is org.h2.jdbc.JdbcSQLDataException: Value too long for column "FIRST_NAME VARCHAR(5)": "'Shailendra' (10)"; SQL statement:
insert into TABLE1(FIRST_NAME) values (?) [22001-200]
2021-10-11 15:22:22.941 TRACE 23124 --- [           main] **o.s.t.i.RuleBasedTransactionAttribute    : Applying rules to determine whether transaction should rollback on org.springframework.dao.DataIntegrityViolationException: PreparedStatementCallback; SQL [insert into TABLE1(FIRST_NAME) values (?)]; Value too long for column "FIRST_NAME VARCHAR(5)": "'Shailendra' (10)"; SQL statement:**
insert into TABLE1(FIRST_NAME) values (?) [22001-200]; nested exception is org.h2.jdbc.JdbcSQLDataException: Value too long for column "FIRST_NAME VARCHAR(5)": "'Shailendra' (10)"; SQL statement:
insert into TABLE1(FIRST_NAME) values (?) [22001-200]
2021-10-11 15:22:22.941 TRACE 23124 --- [           main] o.s.t.i.RuleBasedTransactionAttribute    : Winning rollback rule is: null
2021-10-11 15:22:22.941 TRACE 23124 --- [           main] **o.s.t.i.RuleBasedTransactionAttribute    : No relevant rollback rule found: applying default rules**
2021-10-11 15:22:22.941  INFO 23124 --- [           main] c.e.managingtransactions.AppRunner       : --- The following exception is expect because 'Shailendra' is too big for the DB ---v
2021-10-11 15:22:22.941 ERROR 23124 --- [           main] c.e.managingtransactions.AppRunner       : PreparedStatementCallback; SQL [insert into TABLE1(FIRST_NAME) values (?)]; Value too long for column "FIRST_NAME VARCHAR(5)": "'Shailendra' (10)"; SQL statement:
insert into TABLE1(FIRST_NAME) values (?) [22001-200]; nested exception is org.h2.jdbc.JdbcSQLDataException: Value too long for column "FIRST_NAME VARCHAR(5)": "'Shailendra' (10)"; SQL statement:
insert into TABLE1(FIRST_NAME) values (?) [22001-200]

更新:

即使我使用 batchUpdate 方法,结果仍然相同

SqlParameterSource[] params = new SqlParameterSource[] { new MapSqlParameterSource("FIRST_NAME", 1),

    };
    
    jdbcTemplate.batchUpdate("insert into TABLE1(FIRST_NAME) values (:FIRST_NAME)", params);

对应日志

2021-10-12 00:12:42.075 TRACE 22352 --- [           main] o.s.t.i.TransactionInterceptor           : Getting transaction for [com.example.managingtransactions.TransactionTestService.bookInTransaction]
2021-10-12 00:12:42.094  INFO 22352 --- [           main] c.e.m.TransactionTestService             : Booking Alice in a seat...
2021-10-12 00:12:42.134  INFO 22352 --- [           main] c.e.m.TransactionTestService             : Booking Bob in a seat...
2021-10-12 00:12:42.134  INFO 22352 --- [           main] c.e.m.TransactionTestService             : Booking Shailendra in a seat...
2021-10-12 00:12:42.385 TRACE 22352 --- [           main] o.s.t.i.TransactionInterceptor           : Completing transaction for [com.example.managingtransactions.TransactionTestService.bookInTransaction] after exception: org.springframework.dao.DataIntegrityViolationException: PreparedStatementCallback; SQL [insert into TABLE1(FIRST_NAME) values (?)]; Value too long for column "FIRST_NAME VARCHAR(5)": "'Shailendra' (10)"; SQL statement:
insert into TABLE1(FIRST_NAME) values (?) [22001-200]; nested exception is org.h2.jdbc.JdbcSQLDataException: Value too long for column "FIRST_NAME VARCHAR(5)": "'Shailendra' (10)"; SQL statement:
insert into TABLE1(FIRST_NAME) values (?) [22001-200]
2021-10-12 00:12:42.385 TRACE 22352 --- [           main] o.s.t.i.RuleBasedTransactionAttribute    : Applying rules to determine whether transaction should rollback on org.springframework.dao.DataIntegrityViolationException: PreparedStatementCallback; SQL [insert into TABLE1(FIRST_NAME) values (?)]; Value too long for column "FIRST_NAME VARCHAR(5)": "'Shailendra' (10)"; SQL statement:
insert into TABLE1(FIRST_NAME) values (?) [22001-200]; nested exception is org.h2.jdbc.JdbcSQLDataException: Value too long for column "FIRST_NAME VARCHAR(5)": "'Shailendra' (10)"; SQL statement:
insert into TABLE1(FIRST_NAME) values (?) [22001-200]
2021-10-12 00:12:42.385 TRACE 22352 --- [           main] o.s.t.i.RuleBasedTransactionAttribute    : Winning rollback rule is: null
2021-10-12 00:12:42.385 TRACE 22352 --- [           main] o.s.t.i.RuleBasedTransactionAttribute    : No relevant rollback rule found: applying default rules
2021-10-12 00:12:42.385  INFO 22352 --- [           main] c.e.managingtransactions.AppRunner       : --- The following exception is expect because 'Shailendra' is too big for the DB ---v
2021-10-12 00:12:42.385 ERROR 22352 --- [           main] c.e.managingtransactions.AppRunner       : PreparedStatementCallback; SQL [insert into TABLE1(FIRST_NAME) values (?)]; Value too long for column "FIRST_NAME VARCHAR(5)": "'Shailendra' (10)"; SQL statement:
insert into TABLE1(FIRST_NAME) values (?) [22001-200]; nested exception is org.h2.jdbc.JdbcSQLDataException: Value too long for column "FIRST_NAME VARCHAR(5)": "'Shailendra' (10)"; SQL statement:
insert into TABLE1(FIRST_NAME) values (?) [22001-200]

应用程序.yml

logging:
    level:
        org.springframework:
            transaction:
               support: DEBUG
               interceptor: TRACE

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM