当 spring 引导应用程序是 运行 来自 java -jar 时未提交事务

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

我们使用 maven spring-boot.

开发了一个应用程序

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

我们正在对 Jpa 存储库使用 @Transactional 注释。当我们将记录器设置为所有级别时,我们可以看到调试日志和构建日志之间的差异。 调试正在处理 org.springframework.orm.jpa.JpaTransactionManager 的事务,但构建不是。构建正在使用 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());
    }
}
}

我们在调试和 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

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

[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" />
    (使用 this link and this link 获取更多信息)
  2. 在 application.properties 中使用此 spring.datasource.auto-commit=false 并从您的代码中提交。
    这是给你的答案!我想知道你一定有一个!
    将 autoCommit 设置为 false 是正确的做法。
    我所知道的所有 RDBMS 都在最后提交事务,除非明确回滚。你看到不同的行为了吗?如果您怀疑有问题,一种选择是在数据库服务器中打开日志记录,您可以在其中看到提交请求。

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

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

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

TLDR:JPA 实体不适用于 DataSourceTransactionManager。