繁体   English   中英

从 java -jar 运行 Spring Boot 应用程序时未提交事务

[英]Transaction is not committed when spring boot application is run from java -jar

我们使用 maven spring-boot 开发了一个应用程序。

当我们使用 NetDeans IDE 运行项目时,一切正常。 但是当我们构建它并从 java -jar 命令运行它时,它似乎可以工作并且不进行数据库更新。 另一方面,它可以从数据库中读取。

我们在 Jpa 存储库中使用@Transactional注释。 当我们将 loggers 设置为 ALL 级别时,我们可以看到调试日志和构建日志之间的差异。 Debug 正在使用org.springframework.orm.jpa.JpaTransactionManager处理事务,但 build 不是。 构建使用org.springframework.jdbc.datasource.DataSourceTransactionManager

正如你在下面看到的,日志有一些差异
工作一

[DEBUG] 2019-12-20 10:50:32,431 org.springframework.orm.jpa.JpaTransactionManager getTransaction - Creating new transaction with name [com.sportbook.bets.services.BetsServices.updateScheduledTasks]: PROPAGATION_REQUIRED,ISOLATION_DEFAULT; 'transactionManager'
[TRACE] 2019-12-20 10:50:32,431 org.hibernate.internal.SessionFactoryImpl$SessionBuilderImpl openSession - Opening Hibernate Session.  tenant=null, owner=null
[TRACE] 2019-12-20 10:50:32,431 org.hibernate.internal.SessionImpl <init> - Opened Session [4685449c-c855-4806-a2a0-9ae8cdcd3e10] at timestamp: 1576835432431
[DEBUG] 2019-12-20 10:50:32,432 org.springframework.orm.jpa.JpaTransactionManager doBegin - Opened new EntityManager [SessionImpl(127972401PersistenceContext[entityKeys=[],collectionKeys=[]];ActionQueue[insertions=ExecutableList{size=0} updates=ExecutableList{size=0} deletions=ExecutableList{size=0} orphanRemovals=ExecutableList{size=0} collectionCreations=ExecutableList{size=0} collectionRemovals=ExecutableList{size=0} collectionUpdates=ExecutableList{size=0} collectionQueuedOps=ExecutableList{size=0} unresolvedInsertDependencies=null])] for JPA transaction
[DEBUG] 2019-12-20 10:50:32,432 org.hibernate.engine.transaction.internal.TransactionImpl <init> - On TransactionImpl creation, JpaCompliance#isJpaTransactionComplianceEnabled == false
[DEBUG] 2019-12-20 10:50:32,432 org.hibernate.engine.transaction.internal.TransactionImpl begin - begin
[TRACE] 2019-12-20 10:50:32,432 org.hibernate.resource.jdbc.internal.AbstractLogicalConnectionImplementor begin - Preparing to begin transaction via JDBC Connection.setAutoCommit(false)
[TRACE] 2019-12-20 10:50:32,459 org.hibernate.resource.jdbc.internal.AbstractLogicalConnectionImplementor begin - Transaction begun via JDBC Connection.setAutoCommit(false)
[TRACE] 2019-12-20 10:50:32,460 org.hibernate.resource.transaction.backend.jdbc.internal.JdbcResourceLocalTransactionCoordinatorImpl afterBeginCallback - ResourceLocalTransactionCoordinatorImpl#afterBeginCallback
[DEBUG] 2019-12-20 10:50:32,460 org.springframework.orm.jpa.JpaTransactionManager doBegin - Exposing JPA transaction as JDBC [org.springframework.orm.jpa.vendor.HibernateJpaDialect$HibernateConnectionHandle@640b7957]
[TRACE] 2019-12-20 10:50:32,460 org.springframework.transaction.support.TransactionSynchronizationManager bindResource - Bound value [org.springframework.jdbc.datasource.ConnectionHolder@67406405] for key [HikariDataSource (HikariPool-1)] to thread [default_task_executor_thread1]
[TRACE] 2019-12-20 10:50:32,460 org.springframework.transaction.support.TransactionSynchronizationManager bindResource - Bound value [org.springframework.orm.jpa.EntityManagerHolder@7c8d5edd] for key [org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean@6f59896c] to thread [default_task_executor_thread1]
[TRACE] 2019-12-20 10:50:32,460 org.springframework.transaction.support.TransactionSynchronizationManager initSynchronization - Initializing transaction synchronization
[TRACE] 2019-12-20 10:50:32,460 org.springframework.transaction.interceptor.TransactionInterceptor prepareTransactionInfo - Getting transaction for [com.sportbook.bets.services.BetsServices.updateScheduledTasks]
[TRACE] 2019-12-20 10:50:32,460 org.springframework.transaction.support.TransactionSynchronizationManager bindResource - Bound value [org.springframework.data.jpa.repository.support.CrudMethodMetadataPostProcessor$DefaultCrudMethodMetadata@7e8e7c41] for key [public abstract java.lang.Object org.springframework.data.repository.CrudRepository.save(java.lang.Object)] to thread [default_task_executor_thread1]
[DEBUG] 2019-12-20 10:50:32,461 org.springframework.data.repository.core.support.TransactionalRepositoryProxyPostProcessor$CustomAnnotationTransactionAttributeSource getTransactionAttribute - Adding transactional method 'save' with attribute: PROPAGATION_REQUIRED,ISOLATION_DEFAULT
[TRACE] 2019-12-20 10:50:32,461 org.springframework.beans.factory.support.DefaultListableBeanFactory doGetBean - Returning cached instance of singleton bean 'transactionManager'
[TRACE] 2019-12-20 10:50:32,461 org.springframework.transaction.support.TransactionSynchronizationManager getResource - Retrieved value [org.springframework.orm.jpa.EntityManagerHolder@7c8d5edd] for key [org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean@6f59896c] bound to thread [default_task_executor_thread1]
[DEBUG] 2019-12-20 10:50:32,461 org.springframework.orm.jpa.JpaTransactionManager doGetTransaction - Found thread-bound EntityManager [SessionImpl(127972401PersistenceContext[entityKeys=[],collectionKeys=[]];ActionQueue[insertions=ExecutableList{size=0} updates=ExecutableList{size=0} deletions=ExecutableList{size=0} orphanRemovals=ExecutableList{size=0} collectionCreations=ExecutableList{size=0} collectionRemovals=ExecutableList{size=0} collectionUpdates=ExecutableList{size=0} collectionQueuedOps=ExecutableList{size=0} unresolvedInsertDependencies=null])] for JPA transaction
[TRACE] 2019-12-20 10:50:32,461 org.springframework.transaction.support.TransactionSynchronizationManager getResource - Retrieved value [org.springframework.jdbc.datasource.ConnectionHolder@67406405] for key [HikariDataSource (HikariPool-1)] bound to thread [default_task_executor_thread1]
[DEBUG] 2019-12-20 10:50:32,461 org.springframework.orm.jpa.JpaTransactionManager handleExistingTransaction - Participating in existing transaction
[TRACE] 2019-12-20 10:50:32,461 org.springframework.transaction.interceptor.TransactionInterceptor prepareTransactionInfo - Getting transaction for [org.springframework.data.jpa.repository.support.SimpleJpaRepository.save]
[TRACE] 2019-12-20 10:50:32,464 org.springframework.beans.CachedIntrospectionResults <init> - Getting BeanInfo for class [com.sportbook.bets.entities.ScheduledTasksLog]
[TRACE] 2019-12-20 10:50:32,465 org.springframework.beans.CachedIntrospectionResults <init> - Caching PropertyDescriptors for class [com.sportbook.bets.entities.ScheduledTasksLog]
[TRACE] 2019-12-20 10:50:32,466 org.springframework.beans.CachedIntrospectionResults <init> - Found bean property 'class' of type [java.lang.Class]
[TRACE] 2019-12-20 10:50:32,466 org.springframework.beans.CachedIntrospectionResults <init> - Found bean property 'id' of type [java.lang.Integer]

不工作

[DEBUG] 2019-12-20 10:45:27,177 org.springframework.jdbc.datasource.DataSourceTransactionManager getTransaction - Creating new transaction with name [com.sportbook.bets.services.BetsServices.updateScheduledTasks]: PROPAGATION_REQUIRED,ISOLATION_DEFAULT; 'transactionManager'
[DEBUG] 2019-12-20 10:45:27,177 org.springframework.jdbc.datasource.DataSourceTransactionManager doBegin - Acquired Connection [HikariProxyConnection@32188486 wrapping com.mysql.cj.jdbc.ConnectionImpl@1dc5318] for JDBC transaction
[DEBUG] 2019-12-20 10:45:27,177 org.springframework.jdbc.datasource.DataSourceTransactionManager doBegin - Switching JDBC Connection [HikariProxyConnection@32188486 wrapping com.mysql.cj.jdbc.ConnectionImpl@1dc5318] to manual commit
[TRACE] 2019-12-20 10:45:27,201 org.springframework.transaction.support.TransactionSynchronizationManager bindResource - Bound value [org.springframework.jdbc.datasource.ConnectionHolder@13277ad] for key [HikariDataSource (HikariPool-1)] to thread [default_task_executor_thread2]
[TRACE] 2019-12-20 10:45:27,201 org.springframework.transaction.support.TransactionSynchronizationManager initSynchronization - Initializing transaction synchronization
[TRACE] 2019-12-20 10:45:27,201 org.springframework.transaction.interceptor.TransactionInterceptor prepareTransactionInfo - Getting transaction for [com.sportbook.bets.services.BetsServices.updateScheduledTasks]
[TRACE] 2019-12-20 10:45:27,201 org.springframework.transaction.support.TransactionSynchronizationManager bindResource - Bound value [org.springframework.data.jpa.repository.support.CrudMethodMetadataPostProcessor$DefaultCrudMethodMetadata@1b7705] for key [public abstract java.lang.Object org.springframework.data.repository.CrudRepository.save(java.lang.Object)] to thread [default_task_executor_thread2]
[TRACE] 2019-12-20 10:45:27,201 org.springframework.transaction.support.TransactionSynchronizationManager getResource - Retrieved value [org.springframework.jdbc.datasource.ConnectionHolder@13277ad] for key [HikariDataSource (HikariPool-1)] bound to thread [default_task_executor_thread2]
[DEBUG] 2019-12-20 10:45:27,201 org.springframework.jdbc.datasource.DataSourceTransactionManager handleExistingTransaction - Participating in existing transaction
[TRACE] 2019-12-20 10:45:27,201 org.springframework.transaction.interceptor.TransactionInterceptor prepareTransactionInfo - Getting transaction for [org.springframework.data.jpa.repository.support.SimpleJpaRepository.save]
[DEBUG] 2019-12-20 10:45:27,201 org.springframework.orm.jpa.EntityManagerFactoryUtils doGetTransactionalEntityManager - Opening JPA EntityManager

我无法放置所有日志输出,但我认为这些小部件可以提供某些方面。 知道为什么会发生这种情况吗?

更新

我的数据源配置:

@Configuration
@EnableJpaRepositories(
    basePackages = "com.appdomain.testApp.repositories",
    entityManagerFactoryRef = "testAppEntityManagerFactory",
    transactionManagerRef = "transactionManager"
)
@EnableTransactionManagement
public class TestAppDataSourceConfig {

@Autowired
private Environment env;

@Bean
@Primary
@ConfigurationProperties(prefix = "spring.datasource.data1")
public DataSourceProperties testAppDataSourceProperties() {
    return new DataSourceProperties();
}

@Bean
@Primary
public DataSource testAppDataSource() {
    DataSourceProperties testAppDataSourceProperties = testAppDataSourceProperties();
    return DataSourceBuilder.create()
            .driverClassName(testAppDataSourceProperties.getDriverClassName())
            .url(testAppDataSourceProperties.getUrl())
            .username(testAppDataSourceProperties.getUsername())
            .password(testAppDataSourceProperties.getPassword())
            .build();
}

@Bean
@Primary
public PlatformTransactionManager transactionManager() {
    EntityManagerFactory factory = testAppEntityManagerFactory().getObject();
    return new JpaTransactionManager(factory);
}

@Bean(name="testAppEntityManagerFactory")
@Primary
public LocalContainerEntityManagerFactoryBean testAppEntityManagerFactory() {
    LocalContainerEntityManagerFactoryBean factory = new LocalContainerEntityManagerFactoryBean();
    factory.setDataSource(testAppDataSource());
    factory.setPackagesToScan(new String[]{"com.appdomain.testApp.entities"});
    factory.setJpaVendorAdapter(new HibernateJpaVendorAdapter());
    Properties jpaProperties = new Properties();
    jpaProperties.put("hibernate.hbm2ddl.auto", env.getProperty("spring.jpa.hibernate.ddl-auto"));
    jpaProperties.put("hibernate.show-sql", env.getProperty("spring.jpa.show-sql"));
    jpaProperties.put("hibernate.dialect", "org.hibernate.dialect.MySQL5Dialect");
    factory.setJpaProperties(jpaProperties);
    return factory;

}

@Bean
@Primary
public DataSourceInitializer testAppDataSourceInitializer() {
    DataSourceInitializer dataSourceInitializer = new DataSourceInitializer();
    dataSourceInitializer.setDataSource(testAppDataSource());
    dataSourceInitializer.setEnabled(env.getProperty("spring.datasource.data1.initialize", Boolean.class, false));
    return dataSourceInitializer;
}
}

我的交易服务方式:

@Transactional("transactionManager")
public ScheduledTasksLog updateScheduledTasks(ScheduledTasksLog scheduledTasksLog) {
    return scheduledTasksLogRepository.save(scheduledTasksLog);
}

@Transactional("transactionManager")
public ScheduledTasksLog getScheduledTasksLogByTaskName(String taskName) {
    return scheduledTasksLogRepository.findByTaskName(taskName);
}

我的实体存储库:

@Repository
public interface ScheduledTasksLogRepository  extends 
JpaRepository<ScheduledTasksLog, Integer> {
ScheduledTasksLog findByTaskName(String taskName);

}

我的 appsetting.properties:

jms.enabled=true

debug=true

spring.datasource.auto-commit=false

spring.datasource.data1.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.data1.url=jdbc:mysql://localhost:3306/xx?useSSL=false
spring.datasource.data1.username=
spring.datasource.data1.password=
spring.datasource.data1.initialize=true

spring.datasource.data2.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.data2.url=jdbc:mysql://localhost:3306/xxx?useSSL=false
spring.datasource.data2.username=
spring.datasource.data2.password=
spring.datasource.data2.initialize=true

spring.jpa.hibernate.ddl-auto=update
spring.jpa.show-sql=true
spring.jpa.database=default

eureka.client.enabled=false

# port
server.port=8667

proxyclient.baseuri =http://localhost:9999

spring.batch.job.enabled=false

spring.batch.initialize-schema=always

spring.main.allow-bean-definition-overriding=true

我调用事务服务方法的计划任务:

@EnableAsync
@Component
@ComponentScan(basePackages = "com.domain.message")
@EnableScheduling
public class ScheduledTasks {



@Autowired
private Sender sender;

@Autowired
private TestService testService;

@Autowired
private Environment env;

@Async
@Scheduled(fixedRate = 40000)
public void testtask() {
    try {
        logger.info("The time is now:" + dateFormat.format(new Date()));

        ScheduledTasksLog scheduledTasksLog = testService.getScheduledTasksLogByTaskName("testtask");
        long interval = 0;
        if (scheduledTasksLog != null) {
            interval = TimeUnit.SECONDS.convert(Math.abs(new Date().getTime() - scheduledTasksLog.getLastRunDate().getTime()), TimeUnit.MILLISECONDS);
            interval += 3;
            scheduledTasksLog.setLastRunDate(new Timestamp(new Date().getTime()));
        } else {
            interval = 180;
            scheduledTasksLog = new ScheduledTasksLog();
            scheduledTasksLog.setTaskName("testtask");
            scheduledTasksLog.setLastRunDate(new Timestamp(new Date().getTime()));
        }

        testService.updateScheduledTasks(scheduledTasksLog);

    } catch (Exception e) {
        logger.info(e.getMessage());
    }
}
}

我们在 debug 和 java -jar 命令中使用相同的 application.properties 文件。 JpaRepository 自己处理事务。 我们不回滚或提交。 我们如何手动提交它?

日志的事务提交部分:工作一:

[TRACE] 2019-12-20 10:50:32,552 org.hibernate.resource.jdbc.internal.AbstractLogicalConnectionImplementor commit - Preparing to commit transaction via JDBC Connection.commit()
[TRACE] 2019-12-20 10:50:32,581 org.hibernate.resource.jdbc.internal.AbstractLogicalConnectionImplementor commit - Transaction committed via JDBC Connection.commit()
[TRACE] 2019-12-20 10:50:32,581 org.hibernate.resource.jdbc.internal.AbstractLogicalConnectionImplementor resetConnection - re-enabling auto-commit on JDBC Connection after completion of JDBC-based transaction
[TRACE] 2019-12-20 10:50:32,609 org.springframework.jms.listener.DefaultMessageListenerContainer doReceiveAndExecute - Consumer [ActiveMQMessageConsumer { value=ID:DESKTOP-LNDR73U-54344-1576835431439-1:1:1:1, started=true }] of session [ActiveMQSession {id=ID:DESKTOP-LNDR73U-54344-1576835431439-1:1:1,started=true} java.lang.Object@1012d727] did not receive a message
[TRACE] 2019-12-20 10:50:32,609 org.hibernate.resource.jdbc.internal.AbstractLogicalConnectionImplementor afterTransaction - LogicalConnection#afterTransaction
[TRACE] 2019-12-20 10:50:32,609 org.hibernate.resource.jdbc.internal.ResourceRegistryStandardImpl releaseResources - Releasing JDBC resources
[TRACE] 2019-12-20 10:50:32,609 org.hibernate.resource.transaction.backend.jdbc.internal.JdbcResourceLocalTransactionCoordinatorImpl afterCompletionCallback - ResourceLocalTransactionCoordinatorImpl#afterCompletionCallback(true)
[TRACE] 2019-12-20 10:50:32,610 org.hibernate.resource.transaction.internal.SynchronizationRegistryStandardImpl tracef - SynchronizationRegistryStandardImpl.notifySynchronizationsAfterTransactionCompletion(3)
[TRACE] 2019-12-20 10:50:32,610 org.hibernate.internal.SessionImpl afterTransactionCompletion - SessionImpl#afterTransactionCompletion(successful=true, delayed=false)
[TRACE] 2019-12-20 10:50:32,610 org.springframework.orm.jpa.JpaTransactionManager triggerAfterCommit - Triggering afterCommit synchronization
[TRACE] 2019-12-20 10:50:32,610 org.springframework.transaction.support.TransactionSynchronizationManager clearSynchronization - Clearing transaction synchronization
[TRACE] 2019-12-20 10:50:32,610 org.springframework.orm.jpa.JpaTransactionManager triggerAfterCompletion - Triggering afterCompletion synchronization
[TRACE] 2019-12-20 10:50:32,610 org.springframework.transaction.support.TransactionSynchronizationManager doUnbindResource - Removed value [org.springframework.orm.jpa.EntityManagerHolder@7c8d5edd] for key [org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean@6f59896c] from thread [default_task_executor_thread1]
[TRACE] 2019-12-20 10:50:32,610 org.springframework.transaction.support.TransactionSynchronizationManager doUnbindResource - Removed value [org.springframework.jdbc.datasource.ConnectionHolder@67406405] for key [HikariDataSource (HikariPool-1)] from thread [default_task_executor_thread1]
[DEBUG] 2019-12-20 10:50:32,610 org.springframework.orm.jpa.JpaTransactionManager doCleanupAfterCompletion - Closing JPA EntityManager [SessionImpl(127972401PersistenceContext[entityKeys=[EntityKey[com.domain.testapp.entities.ScheduledTasksLog#2]],collectionKeys=[]];ActionQueue[insertions=ExecutableList{size=0} updates=ExecutableList{size=0} deletions=ExecutableList{size=0} orphanRemovals=ExecutableList{size=0} collectionCreations=ExecutableList{size=0} collectionRemovals=ExecutableList{size=0} collectionUpdates=ExecutableList{size=0} collectionQueuedOps=ExecutableList{size=0} unresolvedInsertDependencies=null])] after transaction
[TRACE] 2019-12-20 10:50:32,610 org.hibernate.internal.SessionImpl closeWithoutOpenChecks - Closing session [4685449c-c855-4806-a2a0-9ae8cdcd3e10]
[TRACE] 2019-12-20 10:50:32,610 org.hibernate.engine.jdbc.internal.JdbcCoordinatorImpl close - Closing JDBC container [org.hibernate.engine.jdbc.internal.JdbcCoordinatorImpl@18320c9f]
[TRACE] 2019-12-20 10:50:32,610 org.hibernate.resource.jdbc.internal.ResourceRegistryStandardImpl releaseResources - Releasing JDBC resources
[TRACE] 2019-12-20 10:50:32,611 org.hibernate.resource.jdbc.internal.LogicalConnectionManagedImpl close - Closing logical connection
[TRACE] 2019-12-20 10:50:32,611 org.hibernate.resource.jdbc.internal.ResourceRegistryStandardImpl releaseResources - Releasing JDBC resources
[TRACE] 2019-12-20 10:50:32,611 org.hibernate.resource.jdbc.internal.LogicalConnectionManagedImpl close - Logical connection closed

不工作:

[TRACE] 2019-12-20 10:45:27,229 org.hibernate.type.descriptor.sql.BasicExtractor extract - extracted value ([lastrund2_2_0_] : [TIMESTAMP]) - [2019-12-20 08:00:06.0]
[TRACE] 2019-12-20 10:45:27,229 org.hibernate.type.descriptor.sql.BasicExtractor extract - extracted value ([taskname3_2_0_] : [VARCHAR]) - [testtask]
[TRACE] 2019-12-20 10:45:27,229 org.hibernate.loader.Loader processResultSet - Done processing result set (1 rows)
[TRACE] 2019-12-20 10:45:27,229 org.hibernate.loader.Loader initializeEntitiesAndCollections - Total objects hydrated: 1
[DEBUG] 2019-12-20 10:45:27,229 org.hibernate.engine.internal.TwoPhaseLoad doInitializeEntity - Resolving associations for [com.domain.testapp.entities.ScheduledTasksLog#2]
[DEBUG] 2019-12-20 10:45:27,229 org.hibernate.engine.internal.TwoPhaseLoad doInitializeEntity - Done materializing entity [com.domain.testapp.entities.ScheduledTasksLog#2]
[TRACE] 2019-12-20 10:45:27,230 org.hibernate.resource.jdbc.internal.ResourceRegistryStandardImpl release - Releasing statement [HikariProxyPreparedStatement@32276991 wrapping com.mysql.cj.jdbc.ClientPreparedStatement: select scheduledt0_.id as id1_2_0_, scheduledt0_.lastrundate as lastrund2_2_0_, scheduledt0_.taskname as taskname3_2_0_ from scheduled_tasks scheduledt0_ where scheduledt0_.id=2]
[TRACE] 2019-12-20 10:45:27,230 org.hibernate.resource.jdbc.internal.ResourceRegistryStandardImpl close - Closing result set [HikariProxyResultSet@20385840 wrapping com.mysql.cj.jdbc.result.ResultSetImpl@139168f]
[TRACE] 2019-12-20 10:45:27,230 org.hibernate.resource.jdbc.internal.ResourceRegistryStandardImpl close - Closing prepared statement [HikariProxyPreparedStatement@32276991 wrapping com.mysql.cj.jdbc.ClientPreparedStatement: select scheduledt0_.id as id1_2_0_, scheduledt0_.lastrundate as lastrund2_2_0_, scheduledt0_.taskname as taskname3_2_0_ from scheduled_tasks scheduledt0_ where scheduledt0_.id=2]
[TRACE] 2019-12-20 10:45:27,230 org.hibernate.engine.jdbc.internal.JdbcCoordinatorImpl afterStatementExecution - Starting after statement execution processing [ON_CLOSE]
[TRACE] 2019-12-20 10:45:27,230 org.hibernate.engine.internal.StatefulPersistenceContext initializeNonLazyCollections - Initializing non-lazy collections
[DEBUG] 2019-12-20 10:45:27,230 org.hibernate.loader.Loader loadEntity - Done entity load
[TRACE] 2019-12-20 10:45:27,230 org.springframework.transaction.interceptor.TransactionInterceptor commitTransactionAfterReturning - Completing transaction for [org.springframework.data.jpa.repository.support.SimpleJpaRepository.save]
[TRACE] 2019-12-20 10:45:27,230 org.springframework.transaction.support.TransactionSynchronizationManager doUnbindResource - Removed value [org.springframework.data.jpa.repository.support.CrudMethodMetadataPostProcessor$DefaultCrudMethodMetadata@1b7705] for key [public abstract java.lang.Object org.springframework.data.repository.CrudRepository.save(java.lang.Object)] from thread [default_task_executor_thread2]
[TRACE] 2019-12-20 10:45:27,230 org.springframework.transaction.interceptor.TransactionInterceptor commitTransactionAfterReturning - Completing transaction for [com.domain.testapp.services.testservice.updateScheduledTasks]
[TRACE] 2019-12-20 10:45:27,231 org.springframework.jdbc.datasource.DataSourceTransactionManager triggerBeforeCommit - Triggering beforeCommit synchronization
[TRACE] 2019-12-20 10:45:27,231 org.springframework.jdbc.datasource.DataSourceTransactionManager triggerBeforeCompletion - Triggering beforeCompletion synchronization
[TRACE] 2019-12-20 10:45:27,231 org.springframework.transaction.support.TransactionSynchronizationManager doUnbindResource - Removed value [org.springframework.orm.jpa.EntityManagerHolder@1093840] for key [org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean@155cf22] from thread [default_task_executor_thread2]
[TRACE] 2019-12-20 10:45:27,231 org.hibernate.internal.SessionImpl closeWithoutOpenChecks - Closing session [55b47b79-008e-4f4a-b6d7-4c33c302171e]
[TRACE] 2019-12-20 10:45:27,231 org.hibernate.engine.jdbc.internal.JdbcCoordinatorImpl close - Closing JDBC container [org.hibernate.engine.jdbc.internal.JdbcCoordinatorImpl@afa702]
[TRACE] 2019-12-20 10:45:27,231 org.hibernate.resource.jdbc.internal.ResourceRegistryStandardImpl releaseResources - Releasing JDBC resources
[TRACE] 2019-12-20 10:45:27,231 org.hibernate.resource.jdbc.internal.LogicalConnectionManagedImpl close - Closing logical connection
[TRACE] 2019-12-20 10:45:27,231 org.hibernate.resource.jdbc.internal.ResourceRegistryStandardImpl releaseResources - Releasing JDBC resources
[TRACE] 2019-12-20 10:45:27,231 org.hibernate.resource.jdbc.internal.LogicalConnectionManagedImpl close - Logical connection closed
[DEBUG] 2019-12-20 10:45:27,231 org.springframework.jdbc.datasource.DataSourceTransactionManager processCommit - Initiating transaction commit
[DEBUG] 2019-12-20 10:45:27,231 org.springframework.jdbc.datasource.DataSourceTransactionManager doCommit - Committing JDBC transaction on Connection [HikariProxyConnection@32188486 wrapping com.mysql.cj.jdbc.ConnectionImpl@1dc5318]
[TRACE] 2019-12-20 10:45:27,253 org.springframework.jdbc.datasource.DataSourceTransactionManager triggerAfterCommit - Triggering afterCommit synchronization
[TRACE] 2019-12-20 10:45:27,253 org.springframework.transaction.support.TransactionSynchronizationManager clearSynchronization - Clearing transaction synchronization
[TRACE] 2019-12-20 10:45:27,254 org.springframework.jdbc.datasource.DataSourceTransactionManager triggerAfterCompletion - Triggering afterCompletion synchronization
[TRACE] 2019-12-20 10:45:27,254 org.springframework.transaction.support.TransactionSynchronizationManager doUnbindResource - Removed value [org.springframework.jdbc.datasource.ConnectionHolder@13277ad] for key [HikariDataSource (HikariPool-1)] from thread [default_task_executor_thread2]
[DEBUG] 2019-12-20 10:45:27,295 org.springframework.jdbc.datasource.DataSourceTransactionManager doCleanupAfterCompletion - Releasing JDBC Connection [HikariProxyConnection@32188486 wrapping com.mysql.cj.jdbc.ConnectionImpl@1dc5318] after transaction

经过几天尝试不同的解决方案,我终于找到了解决方案。

这种情况的原因是我们使用 Spring Batch,它连接了一个名为“transactionManager”的 jdbc 事务管理器。 我们的 jpa 存储库实体无法保存在其中。 所以我们不能添加或更新数据库。

解决方案是我们将主事务管理器命名为“primaryTransactionManager”并在我们的服务中使用它。 我们也在 spring 批处理步骤配置中使用了它。 一切都按预期工作。

TLDR:JPA 实体不适用于 DataSourceTransactionManager。

我注意到下面的工作日志条目。

[TRACE] 2019-12-20 10:50:32,459 org.hibernate.resource.jdbc.internal.AbstractLogicalConnectionImplementor begin - Transaction begun via JDBC Connection.setAutoCommit(false)

我注意到下面不工作的日志条目。

[DEBUG] 2019-12-20 10:45:27,177 org.springframework.jdbc.datasource.DataSourceTransactionManager doBegin - Switching JDBC Connection [HikariProxyConnection@32188486 wrapping com.mysql.cj.jdbc.ConnectionImpl@1dc5318] to manual commit

因此,在比较这两者之后,我认为您的问题可能的解决方案如下。

  1. 在persistence.xml 中使用<property name="hibernate.connection.autocommit" value="true" />
    (使用此链接此链接了解更多信息)
  2. 在 application.properties 中使用此spring.datasource.auto-commit=false并从您的代码中提交它。
    这是你为什么的答案!我想你一定有一个!
    将 autoCommit 设置为 false 是正确的做法。
    除非明确回滚,否则我知道的所有 RDBMS 都会在最后提交事务。 你看到不同的行为了吗? 如果您怀疑有问题,一种选择是打开数据库服务器的日志记录,您可以在其中看到提交请求。

暂无
暂无

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

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