Spring Batch DataSource设置改变了应用程序交易的行为

发布于 2025-01-30 08:26:37 字数 8899 浏览 2 评论 0原文

在我的Spring Boot应用程序中,我有一个JNDI DataSource配置为这样的:

spring:
  datasource:
    jndi-name: java:/users

引入Spring Batch后,某些REST服务的行为发生了变化。

例如,以前的服务具有此日志:

2022-05-19 12:56:27.348 TRACE 667690 --- [default task-1] o.s.b.f.s.DefaultListableBeanFactory     : Returning cached instance of singleton bean 'transactionManager'
2022-05-19 12:56:27.349 DEBUG 667690 --- [default task-1] o.s.orm.jpa.JpaTransactionManager        : Found thread-bound EntityManager [SessionImpl(281567772<open>)] for JPA transaction
2022-05-19 12:56:27.349 DEBUG 667690 --- [default task-1] o.s.orm.jpa.JpaTransactionManager        : Creating new transaction with name [it.ipzs.sgdd.service.UserService.createDelegation]: PROPAGATION_REQUIRED,ISOLATION_DEFAULT
2022-05-19 12:56:27.349 DEBUG 667690 --- [default task-1] o.s.orm.jpa.JpaTransactionManager        : Exposing JPA transaction as JDBC [org.springframework.orm.jpa.vendor.HibernateJpaDialect$HibernateConnectionHandle@7bac569f]
2022-05-19 12:56:27.349 TRACE 667690 --- [default task-1] o.s.t.i.TransactionInterceptor           : Getting transaction for [it.ipzs.sgdd.service.UserService.createDelegation]
2022-05-19 12:56:27.358 DEBUG 667690 --- [default task-1] o.s.orm.jpa.JpaTransactionManager        : Found thread-bound EntityManager [SessionImpl(281567772<open>)] for JPA transaction
2022-05-19 12:56:27.358 DEBUG 667690 --- [default task-1] o.s.orm.jpa.JpaTransactionManager        : Participating in existing transaction
2022-05-19 12:56:27.358 TRACE 667690 --- [default task-1] o.s.t.i.TransactionInterceptor           : Getting transaction for [org.springframework.data.jpa.repository.support.SimpleJpaRepository.findAll]
2022-05-19 12:56:27.361 TRACE 667690 --- [default task-1] o.s.t.i.TransactionInterceptor           : Completing transaction for [org.springframework.data.jpa.repository.support.SimpleJpaRepository.findAll]
2022-05-19 12:56:27.432 TRACE 667690 --- [default task-1] o.s.t.i.TransactionInterceptor           : No need to create transaction for [org.springframework.data.jpa.repository.support.SimpleJpaRepository.countAllBystate]: This method is not transactional.
2022-05-19 12:56:27.437 TRACE 667690 --- [default task-1] o.s.t.i.TransactionInterceptor           : No need to create transaction for [org.springframework.data.jpa.repository.support.SimpleJpaRepository.findByUser]: This method is not transactional.
2022-05-19 12:56:27.442 TRACE 667690 --- [default task-1] o.s.t.i.TransactionInterceptor           : No need to create transaction for [org.springframework.data.jpa.repository.support.SimpleJpaRepository.findByFiscalnumber]: This method is not transactional.
2022-05-19 12:56:27.446 DEBUG 667690 --- [default task-1] o.s.orm.jpa.JpaTransactionManager        : Found thread-bound EntityManager [SessionImpl(281567772<open>)] for JPA transaction
2022-05-19 12:56:27.446 DEBUG 667690 --- [default task-1] o.s.orm.jpa.JpaTransactionManager        : Suspending current transaction, creating new transaction with name [it.ipzs.sgdd.service.SystemService.getKey]
2022-05-19 12:56:27.447 DEBUG 667690 --- [default task-1] o.s.orm.jpa.JpaTransactionManager        : Opened new EntityManager [SessionImpl(1976763709<open>)] for JPA transaction
2022-05-19 12:56:27.531 DEBUG 667690 --- [default task-1] o.s.orm.jpa.JpaTransactionManager        : Exposing JPA transaction as JDBC [org.springframework.orm.jpa.vendor.HibernateJpaDialect$HibernateConnectionHandle@67f4dd10]
2022-05-19 12:56:27.531 TRACE 667690 --- [default task-1] o.s.t.i.TransactionInterceptor           : Getting transaction for [it.ipzs.sgdd.service.SystemService.getKey]

现在相同的服务具有其他日志:

2022-05-19 10:15:52.150 TRACE 661470 --- [default task-1] o.s.b.f.s.DefaultListableBeanFactory     : Returning cached instance of singleton bean 'transactionManager'
2022-05-19 10:15:52.150 DEBUG 661470 --- [default task-1] o.s.j.d.DataSourceTransactionManager     : Creating new transaction with name [it.ipzs.sgdd.service.UserService.createDelegation]: PROPAGATION_REQUIRED,ISOLATION_DEFAULT
2022-05-19 10:15:52.150 DEBUG 661470 --- [default task-1] o.s.j.d.DataSourceTransactionManager     : Acquired Connection [org.jboss.jca.adapters.jdbc.jdk8.WrappedConnectionJDK8@2e37bdd7] for JDBC transaction
2022-05-19 10:15:52.150 DEBUG 661470 --- [default task-1] o.s.j.d.DataSourceTransactionManager     : Switching JDBC Connection [org.jboss.jca.adapters.jdbc.jdk8.WrappedConnectionJDK8@2e37bdd7] to manual commit
2022-05-19 10:15:52.150 TRACE 661470 --- [default task-1] o.s.t.i.TransactionInterceptor           : Getting transaction for [it.ipzs.sgdd.service.UserService.createDelegation]
2022-05-19 10:15:52.157 DEBUG 661470 --- [default task-1] o.s.j.d.DataSourceTransactionManager     : Participating in existing transaction
2022-05-19 10:15:52.157 TRACE 661470 --- [default task-1] o.s.t.i.TransactionInterceptor           : Getting transaction for [org.springframework.data.jpa.repository.support.SimpleJpaRepository.findAll]
2022-05-19 10:15:52.157 DEBUG 661470 --- [default task-1] r$ExtendedEntityManagerInvocationHandler : Starting resource-local transaction on application-managed EntityManager [SessionImpl(184588778<open>)]
2022-05-19 10:15:52.157 DEBUG 661470 --- [default task-1] r$ExtendedEntityManagerInvocationHandler : Joined local transaction
2022-05-19 10:15:52.160 TRACE 661470 --- [default task-1] o.s.t.i.TransactionInterceptor           : Completing transaction for [org.springframework.data.jpa.repository.support.SimpleJpaRepository.findAll]
2022-05-19 10:15:52.213 TRACE 661470 --- [default task-1] o.s.t.i.TransactionInterceptor           : No need to create transaction for [org.springframework.data.jpa.repository.support.SimpleJpaRepository.countAllBystate]: This method is not transactional.
2022-05-19 10:15:52.217 TRACE 661470 --- [default task-1] o.s.t.i.TransactionInterceptor           : No need to create transaction for [org.springframework.data.jpa.repository.support.SimpleJpaRepository.findByUser]: This method is not transactional.
2022-05-19 10:15:52.220 TRACE 661470 --- [default task-1] o.s.t.i.TransactionInterceptor           : No need to create transaction for [org.springframework.data.jpa.repository.support.SimpleJpaRepository.findByFiscalnumber]: This method is not transactional.
2022-05-19 10:15:52.224 DEBUG 661470 --- [default task-1] o.s.j.d.DataSourceTransactionManager     : Suspending current transaction, creating new transaction with name [it.ipzs.sgdd.service.SystemService.getKey]
2022-05-19 10:15:52.300 DEBUG 661470 --- [default task-1] o.s.j.d.DataSourceTransactionManager     : Acquired Connection [org.jboss.jca.adapters.jdbc.jdk8.WrappedConnectionJDK8@6cd14b57] for JDBC transaction
2022-05-19 10:15:52.300 DEBUG 661470 --- [default task-1] o.s.j.d.DataSourceTransactionManager     : Switching JDBC Connection [org.jboss.jca.adapters.jdbc.jdk8.WrappedConnectionJDK8@6cd14b57] to manual commit
2022-05-19 10:15:52.300 TRACE 661470 --- [default task-1] o.s.t.i.TransactionInterceptor           : Getting transaction for [it.ipzs.sgdd.service.SystemService.getKey]

请注意,请注意 datasourcetransactionManager 而不是 jpatransactionManager

我相信不同的行为是由于以下配置引起的,但是我不知道如何在不改变应用程序中的行为的情况下如何做:

@Bean
    BatchConfigurer myBatchConfigurer(@Qualifier("dataSource") DataSource dataSource,
                                      ExecutionContextSerializer executionContextSerializer,
                                      PlatformTransactionManager transactionManager) {
        return new DefaultBatchConfigurer(dataSource) {
            @Override
            protected JobExplorer createJobExplorer() throws Exception {
                JobExplorerFactoryBean jobExplorerFactoryBean = new JobExplorerFactoryBean();
                jobExplorerFactoryBean.setDataSource(dataSource);
                jobExplorerFactoryBean
                        .setSerializer(executionContextSerializer);
                jobExplorerFactoryBean.afterPropertiesSet();
                return jobExplorerFactoryBean.getObject();
            }

            @Override
            protected JobRepository createJobRepository() throws Exception {
                JobRepositoryFactoryBean jobRepositoryFactoryBean = new JobRepositoryFactoryBean();
                jobRepositoryFactoryBean.setDataSource(dataSource);
                jobRepositoryFactoryBean
                        .setSerializer(executionContextSerializer);
                jobRepositoryFactoryBean.setTransactionManager(transactionManager);
                jobRepositoryFactoryBean.setIsolationLevelForCreate("ISOLATION_READ_COMMITTED");
                jobRepositoryFactoryBean.afterPropertiesSet();
                return jobRepositoryFactoryBean.getObject();
            }
        };
    }

In my Spring Boot application I have a JNDI datasource configured like this:

spring:
  datasource:
    jndi-name: java:/users

After the introduction of Spring Batch the behavior of some REST services has changed.

For example, previously a service had this log:

2022-05-19 12:56:27.348 TRACE 667690 --- [default task-1] o.s.b.f.s.DefaultListableBeanFactory     : Returning cached instance of singleton bean 'transactionManager'
2022-05-19 12:56:27.349 DEBUG 667690 --- [default task-1] o.s.orm.jpa.JpaTransactionManager        : Found thread-bound EntityManager [SessionImpl(281567772<open>)] for JPA transaction
2022-05-19 12:56:27.349 DEBUG 667690 --- [default task-1] o.s.orm.jpa.JpaTransactionManager        : Creating new transaction with name [it.ipzs.sgdd.service.UserService.createDelegation]: PROPAGATION_REQUIRED,ISOLATION_DEFAULT
2022-05-19 12:56:27.349 DEBUG 667690 --- [default task-1] o.s.orm.jpa.JpaTransactionManager        : Exposing JPA transaction as JDBC [org.springframework.orm.jpa.vendor.HibernateJpaDialect$HibernateConnectionHandle@7bac569f]
2022-05-19 12:56:27.349 TRACE 667690 --- [default task-1] o.s.t.i.TransactionInterceptor           : Getting transaction for [it.ipzs.sgdd.service.UserService.createDelegation]
2022-05-19 12:56:27.358 DEBUG 667690 --- [default task-1] o.s.orm.jpa.JpaTransactionManager        : Found thread-bound EntityManager [SessionImpl(281567772<open>)] for JPA transaction
2022-05-19 12:56:27.358 DEBUG 667690 --- [default task-1] o.s.orm.jpa.JpaTransactionManager        : Participating in existing transaction
2022-05-19 12:56:27.358 TRACE 667690 --- [default task-1] o.s.t.i.TransactionInterceptor           : Getting transaction for [org.springframework.data.jpa.repository.support.SimpleJpaRepository.findAll]
2022-05-19 12:56:27.361 TRACE 667690 --- [default task-1] o.s.t.i.TransactionInterceptor           : Completing transaction for [org.springframework.data.jpa.repository.support.SimpleJpaRepository.findAll]
2022-05-19 12:56:27.432 TRACE 667690 --- [default task-1] o.s.t.i.TransactionInterceptor           : No need to create transaction for [org.springframework.data.jpa.repository.support.SimpleJpaRepository.countAllBystate]: This method is not transactional.
2022-05-19 12:56:27.437 TRACE 667690 --- [default task-1] o.s.t.i.TransactionInterceptor           : No need to create transaction for [org.springframework.data.jpa.repository.support.SimpleJpaRepository.findByUser]: This method is not transactional.
2022-05-19 12:56:27.442 TRACE 667690 --- [default task-1] o.s.t.i.TransactionInterceptor           : No need to create transaction for [org.springframework.data.jpa.repository.support.SimpleJpaRepository.findByFiscalnumber]: This method is not transactional.
2022-05-19 12:56:27.446 DEBUG 667690 --- [default task-1] o.s.orm.jpa.JpaTransactionManager        : Found thread-bound EntityManager [SessionImpl(281567772<open>)] for JPA transaction
2022-05-19 12:56:27.446 DEBUG 667690 --- [default task-1] o.s.orm.jpa.JpaTransactionManager        : Suspending current transaction, creating new transaction with name [it.ipzs.sgdd.service.SystemService.getKey]
2022-05-19 12:56:27.447 DEBUG 667690 --- [default task-1] o.s.orm.jpa.JpaTransactionManager        : Opened new EntityManager [SessionImpl(1976763709<open>)] for JPA transaction
2022-05-19 12:56:27.531 DEBUG 667690 --- [default task-1] o.s.orm.jpa.JpaTransactionManager        : Exposing JPA transaction as JDBC [org.springframework.orm.jpa.vendor.HibernateJpaDialect$HibernateConnectionHandle@67f4dd10]
2022-05-19 12:56:27.531 TRACE 667690 --- [default task-1] o.s.t.i.TransactionInterceptor           : Getting transaction for [it.ipzs.sgdd.service.SystemService.getKey]

now the same service has this other log:

2022-05-19 10:15:52.150 TRACE 661470 --- [default task-1] o.s.b.f.s.DefaultListableBeanFactory     : Returning cached instance of singleton bean 'transactionManager'
2022-05-19 10:15:52.150 DEBUG 661470 --- [default task-1] o.s.j.d.DataSourceTransactionManager     : Creating new transaction with name [it.ipzs.sgdd.service.UserService.createDelegation]: PROPAGATION_REQUIRED,ISOLATION_DEFAULT
2022-05-19 10:15:52.150 DEBUG 661470 --- [default task-1] o.s.j.d.DataSourceTransactionManager     : Acquired Connection [org.jboss.jca.adapters.jdbc.jdk8.WrappedConnectionJDK8@2e37bdd7] for JDBC transaction
2022-05-19 10:15:52.150 DEBUG 661470 --- [default task-1] o.s.j.d.DataSourceTransactionManager     : Switching JDBC Connection [org.jboss.jca.adapters.jdbc.jdk8.WrappedConnectionJDK8@2e37bdd7] to manual commit
2022-05-19 10:15:52.150 TRACE 661470 --- [default task-1] o.s.t.i.TransactionInterceptor           : Getting transaction for [it.ipzs.sgdd.service.UserService.createDelegation]
2022-05-19 10:15:52.157 DEBUG 661470 --- [default task-1] o.s.j.d.DataSourceTransactionManager     : Participating in existing transaction
2022-05-19 10:15:52.157 TRACE 661470 --- [default task-1] o.s.t.i.TransactionInterceptor           : Getting transaction for [org.springframework.data.jpa.repository.support.SimpleJpaRepository.findAll]
2022-05-19 10:15:52.157 DEBUG 661470 --- [default task-1] r$ExtendedEntityManagerInvocationHandler : Starting resource-local transaction on application-managed EntityManager [SessionImpl(184588778<open>)]
2022-05-19 10:15:52.157 DEBUG 661470 --- [default task-1] r$ExtendedEntityManagerInvocationHandler : Joined local transaction
2022-05-19 10:15:52.160 TRACE 661470 --- [default task-1] o.s.t.i.TransactionInterceptor           : Completing transaction for [org.springframework.data.jpa.repository.support.SimpleJpaRepository.findAll]
2022-05-19 10:15:52.213 TRACE 661470 --- [default task-1] o.s.t.i.TransactionInterceptor           : No need to create transaction for [org.springframework.data.jpa.repository.support.SimpleJpaRepository.countAllBystate]: This method is not transactional.
2022-05-19 10:15:52.217 TRACE 661470 --- [default task-1] o.s.t.i.TransactionInterceptor           : No need to create transaction for [org.springframework.data.jpa.repository.support.SimpleJpaRepository.findByUser]: This method is not transactional.
2022-05-19 10:15:52.220 TRACE 661470 --- [default task-1] o.s.t.i.TransactionInterceptor           : No need to create transaction for [org.springframework.data.jpa.repository.support.SimpleJpaRepository.findByFiscalnumber]: This method is not transactional.
2022-05-19 10:15:52.224 DEBUG 661470 --- [default task-1] o.s.j.d.DataSourceTransactionManager     : Suspending current transaction, creating new transaction with name [it.ipzs.sgdd.service.SystemService.getKey]
2022-05-19 10:15:52.300 DEBUG 661470 --- [default task-1] o.s.j.d.DataSourceTransactionManager     : Acquired Connection [org.jboss.jca.adapters.jdbc.jdk8.WrappedConnectionJDK8@6cd14b57] for JDBC transaction
2022-05-19 10:15:52.300 DEBUG 661470 --- [default task-1] o.s.j.d.DataSourceTransactionManager     : Switching JDBC Connection [org.jboss.jca.adapters.jdbc.jdk8.WrappedConnectionJDK8@6cd14b57] to manual commit
2022-05-19 10:15:52.300 TRACE 661470 --- [default task-1] o.s.t.i.TransactionInterceptor           : Getting transaction for [it.ipzs.sgdd.service.SystemService.getKey]

Please, note the use of DataSourceTransactionManager instead of JpaTransactionManager.

I believe the different behavior is due to the following configuration, but I don't know how to do it without changing the behavior in the rest of the application:

@Bean
    BatchConfigurer myBatchConfigurer(@Qualifier("dataSource") DataSource dataSource,
                                      ExecutionContextSerializer executionContextSerializer,
                                      PlatformTransactionManager transactionManager) {
        return new DefaultBatchConfigurer(dataSource) {
            @Override
            protected JobExplorer createJobExplorer() throws Exception {
                JobExplorerFactoryBean jobExplorerFactoryBean = new JobExplorerFactoryBean();
                jobExplorerFactoryBean.setDataSource(dataSource);
                jobExplorerFactoryBean
                        .setSerializer(executionContextSerializer);
                jobExplorerFactoryBean.afterPropertiesSet();
                return jobExplorerFactoryBean.getObject();
            }

            @Override
            protected JobRepository createJobRepository() throws Exception {
                JobRepositoryFactoryBean jobRepositoryFactoryBean = new JobRepositoryFactoryBean();
                jobRepositoryFactoryBean.setDataSource(dataSource);
                jobRepositoryFactoryBean
                        .setSerializer(executionContextSerializer);
                jobRepositoryFactoryBean.setTransactionManager(transactionManager);
                jobRepositoryFactoryBean.setIsolationLevelForCreate("ISOLATION_READ_COMMITTED");
                jobRepositoryFactoryBean.afterPropertiesSet();
                return jobRepositoryFactoryBean.getObject();
            }
        };
    }

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

愿得七秒忆 2025-02-06 08:26:37

不仅是解决方案,我还找到了解决方法。
由于只需要序列化,我删除了batchconfigurer,并将以下注释添加到DTOS:

@JsonTypeInfo(use = JsonTypeInfo.Id.CLASS)

More than a solution, I found a workaround.
Since only serialization was needed, I deleted the BatchConfigurer and added the following annotation to the DTOs:

@JsonTypeInfo(use = JsonTypeInfo.Id.CLASS)
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文