0

我有一个自定义项目阅读器,它读取数据另一个阅读器是 JdbcCursorItemReader(它从数据库中的请求表中读取数据),构建特定大小的列表并返回项目列表。

请求表具有 id、type 和 status。

我想将阅读器已读取的 ID 的状态更新为 PROCESSING 之类的状态,以便我的应用程序可以显示请求 ID 正在批处理中。此外,在处理项目时,如果有任何业务异常,我想更新具有特定状态的 id 的表。

我希望状态更新部分位于单独的事务中,这样如果一个项目被读取并正在处理,这些请求的状态会显示为 PROCESSING 而不是 REQUESTED。

我在更新请求状态的方法上使用@Transactional(propagation=Propagation.REQUIRES_NE W)。

我为 spring 批处理表和我的应用程序特定表使用单独的数据源和事务管理器。

我正在使用 JDBC 模板来更新状态。

我将 javax.sql.DataSource 用于我的应用程序数据源,将 JpaTransactionManager 用于我的应用程序事务管理器和 HibernateJpaVendorAdapter。

数据库是甲骨文。

当我打开调试日志时,我看到它暂停了主要事务,当从读取器调用更新状态时正在使用一个新事务,它被提交,然后恢复暂停的事务。但我没有看到数据库的变化。事务日志说已提交,但我没有看到数据库中的更改。批处理完成后,我会看到数据库中请求表的更改。我错过了什么吗?

这是日志: 15:40:26 [main] DEBUG o.s.t.a.AnnotationTransactionAttributeSource - Adding transactional method 'updateStatus' with attribute: PROPAGATION_REQUIRES_NEW,ISOLATION_DEFAULT; '' 15:40:48 [main] DEBUG o.s.o.j.JpaTransactionManager - Creating new transaction with name [null]: PROPAGATION_REQUIRED,ISOLATION_DEFAULT 15:40:48 [main] DEBUG o.s.o.j.JpaTransactionManager - Opened new EntityManager [org.hibernate.ejb.EntityManagerImpl@36dd518b] for JPA transaction 15:40:48 [main] DEBUG o.h.e.t.s.AbstractTransactionImpl - begin 15:40:48 [main] DEBUG o.h.e.j.i.LogicalConnectionImpl - Obtaining JDBC connection 15:40:48 [main] DEBUG o.h.e.j.i.LogicalConnectionImpl - Obtained JDBC connection 15:40:48 [main] DEBUG o.h.e.t.i.j.JdbcTransaction - initial autocommit status: true 15:40:48 [main] DEBUG o.h.e.t.i.j.JdbcTransaction - disabling autocommit 15:40:48 [main] DEBUG o.s.o.j.JpaTransactionManager - Exposing JPA transaction as JDBC transaction [org.springframework.orm.jpa.vendor.HibernateJpaDialect$HibernateConnectionHandle@3a7b058e] 15:40:48 [main] INFO c.c.c.f.c.a.b.RequestReader - Reading... 15:40:48 [main] INFO c.c.c.f.c.a.b.SecuritiesReader - End of Input Data from request id ItemReader 15:40:48 [main] DEBUG o.s.o.j.JpaTransactionManager - Creating new transaction with name [*.updateStatus]: PROPAGATION_REQUIRES_NEW,ISOLATION_DEFAULT; '' 15:40:48 [main] DEBUG o.s.o.j.JpaTransactionManager - Opened new EntityManager [org.hibernate.ejb.EntityManagerImpl@628b6e47] for JPA transaction 15:40:48 [main] DEBUG o.h.e.t.s.AbstractTransactionImpl - begin 15:40:48 [main] DEBUG o.h.e.j.i.LogicalConnectionImpl - Obtaining JDBC connection 15:40:48 [main] DEBUG o.h.e.j.i.LogicalConnectionImpl - Obtained JDBC connection 15:40:48 [main] DEBUG o.h.e.t.i.j.JdbcTransaction - initial autocommit status: true 15:40:48 [main] DEBUG o.h.e.t.i.j.JdbcTransaction - disabling autocommit 15:40:48 [main] DEBUG o.s.o.j.JpaTransactionManager - Exposing JPA transaction as JDBC transaction [org.springframework.orm.jpa.vendor.HibernateJpaDialect$HibernateConnectionHandle@88f431d] 15:40:48 [main] INFO c.c.c.f.c.a.b.s.i.InstrumentIdentifierServiceImpl - Updating the status of Request Id's 15:40:48 [main] DEBUG org.hibernate.SQL - UPDATE REQUEST SET STATUS = ? , MESSAGE = ? WHERE ID = ? 15:40:48 [main] DEBUG o.s.o.j.JpaTransactionManager - Initiating transaction commit 15:40:48 [main] DEBUG o.s.o.j.JpaTransactionManager - Committing JPA transaction on EntityManager [org.hibernate.ejb.EntityManagerImpl@628b6e47] 15:40:48 [main] DEBUG o.h.e.t.s.AbstractTransactionImpl - committing 15:40:48 [main] DEBUG o.h.e.t.i.j.JdbcTransaction - committed JDBC Connection 15:40:48 [main] DEBUG o.h.e.t.i.j.JdbcTransaction - re-enabling autocommit 15:40:48 [main] DEBUG o.s.o.j.JpaTransactionManager - Closing JPA EntityManager [org.hibernate.ejb.EntityManagerImpl@628b6e47] after transaction 15:40:48 [main] DEBUG o.s.o.j.EntityManagerFactoryUtils - Closing JPA EntityManager 15:40:48 [main] DEBUG o.h.e.j.i.LogicalConnectionImpl - Releasing JDBC connection 15:40:48 [main] DEBUG o.h.e.j.i.LogicalConnectionImpl - Released JDBC connection 15:40:48 [main] DEBUG o.s.o.j.JpaTransactionManager - Resuming suspended transaction after completion of inner transaction

谢谢!

4

1 回答 1

1

通常,这种情况是使用 ChunkListener 处理的。监听器的 beforeChunk 用于“标记”所有要读取的项目,然后监听器的 afterChunk 处理项目处理后的后续更新。另一种方法是使用 StepExecutionListener 标记步骤中要处理的所有项目。

关于正在发生的事情,听起来您遇到了嵌套事务的问题。由于您有一个外部事务,因此在外部事务提交之前,内部事务不会被应用。

于 2013-11-04T23:37:23.537 回答