SpringBoot交易传播REQUIRES_NEW不会创建新交易

时间:2020-06-29 22:59:33

标签: spring-boot hibernate jpa transactions spring-transactions

我有以下情况:

product

我希望下一个流程:

  1. @Service public class ServiceA { @Autowired private ServiceB serviceB; public void runA(){ serviceB.runB() } } @Service public class ServiceB { @Autowired private ServiceC serviceC; @Transactional public void runB(){ serviceC.runC() ...rest of the logic } } @Service public class ServiceC { @Autowired private TestRepository testRepository; @Transactional(propagation = Propagation.REQUIRES_NEW) public boolean runC(){ Optional<TestEntity> testEntityOptional = testRepository.findByKeyAndType("Key", "Type"); if(testEntityOptional.isPresent()) { testEntityOptional.get().setActive(true); return true; } return false; } } @Transactional public interface TestRepository extends JpaRepository<TestEntity, Integer>, JpaSpecificationExecutor<TestEntity> { @Lock(LockModeType.PESSIMISTIC_WRITE) @QueryHints({@QueryHint(name = "javax.persistence.lock.timeout", value = "5000")}) Optional<TestEntity> findByKeyAndType(@NotNull String key, @NotNull String type); } 调用ServiceA.runA()
  2. ServiceB.runB()打开TRANSACTION_1(或使用事务,如果之前已打开),因为默认传播为ServiceB.runB()
  3. REQUIRED调用ServiceB.runB()
  4. ServiceC.runC()打开TRANSACTION_2,因为传播是ServiceC.runC()
  5. REQUIRED_NEW调用ServiceC.runC()以根据某些条件获取testEntity
  6. TestRepository.findByKeyAndType()从数据库返回符合条件的记录,并将其锁定以进行读取/更新
  7. TestRepository.findByKeyAndType()处理记录
  8. ServiceB.runC()返回值,并且TRANSACTION_2已提交,因此锁已释放
  9. ServiceB.runC()返回并提交TRANSACTION_1

但是从我的测试来看并非如此。它表明ServiceB.runB()即使设置了传播ServiceC.runC()也不会创建新事务(TRANSACTION_2)(或者它不会在返回时提交它),并且仅在REQUIRED_NEW返回时释放锁定(提交TRANSACTION_1时)

有人在这里看到我在做什么错吗?这是SpringBoot的正常行为吗?

另外,锁定超时不起作用: 我正在使用Postgress v10 for DB,其中lock_timeout设置为“ 0”。

因此,ServiceB.runB()似乎无法工作,因为一旦记录被锁定,其他尝试读取记录的事务将挂起一段时间,直到记录被解锁

1 个答案:

答案 0 :(得分:0)

启用logging.level.org.springframework.orm.jpa.JpaTransactionManager=DEBUG后,就会看到此信息。它包括暂停和恢复。

您的交易经理也是JpaTransactionManager吗?

2020-06-30 01:11:53.239 DEBUG 47133 --- [           main] o.s.orm.jpa.JpaTransactionManager        : Creating new transaction with name [com.example.accessingdatajpa.BlogService.save]: PROPAGATION_REQUIRED,ISOLATION_DEFAULT
2020-06-30 01:11:57.532 DEBUG 47133 --- [           main] o.s.orm.jpa.JpaTransactionManager        : Opened new EntityManager [SessionImpl(1968179698<open>)] for JPA transaction
2020-06-30 01:11:57.538 DEBUG 47133 --- [           main] o.s.orm.jpa.JpaTransactionManager        : Exposing JPA transaction as JDBC [org.springframework.orm.jpa.vendor.HibernateJpaDialect$HibernateConnectionHandle@7f2542f]

2020-06-30 01:12:02.432 DEBUG 47133 --- [           main] o.s.orm.jpa.JpaTransactionManager        : Found thread-bound EntityManager [SessionImpl(1968179698<open>)] for JPA transaction
2020-06-30 01:12:04.032 DEBUG 47133 --- [           main] o.s.orm.jpa.JpaTransactionManager        : Suspending current transaction, creating new transaction with name [com.example.accessingdatajpa.Service2.save]
2020-06-30 01:12:06.915 DEBUG 47133 --- [           main] o.s.orm.jpa.JpaTransactionManager        : Opened new EntityManager [SessionImpl(2143659352<open>)] for JPA transaction
2020-06-30 01:12:06.916 DEBUG 47133 --- [           main] o.s.orm.jpa.JpaTransactionManager        : Exposing JPA transaction as JDBC [org.springframework.orm.jpa.vendor.HibernateJpaDialect$HibernateConnectionHandle@42fd8f2f]
2020-06-30 01:12:10.196 DEBUG 47133 --- [           main] o.s.orm.jpa.JpaTransactionManager        : Found thread-bound EntityManager [SessionImpl(2143659352<open>)] for JPA transaction
2020-06-30 01:12:11.489 DEBUG 47133 --- [           main] o.s.orm.jpa.JpaTransactionManager        : Participating in existing transaction

2020-06-30 01:12:12.227 DEBUG 47133 --- [           main] o.s.orm.jpa.JpaTransactionManager        : Initiating transaction commit
2020-06-30 01:12:13.082 DEBUG 47133 --- [           main] o.s.orm.jpa.JpaTransactionManager        : Committing JPA transaction on EntityManager [SessionImpl(2143659352<open>)]
2020-06-30 01:12:13.109 DEBUG 47133 --- [           main] o.s.orm.jpa.JpaTransactionManager        : Closing JPA EntityManager [SessionImpl(2143659352<open>)] after transaction
2020-06-30 01:12:13.110 DEBUG 47133 --- [           main] o.s.orm.jpa.JpaTransactionManager        : Resuming suspended transaction after completion of inner transaction

2020-06-30 01:12:16.409 DEBUG 47133 --- [           main] o.s.orm.jpa.JpaTransactionManager        : Initiating transaction commit
2020-06-30 01:12:17.541 DEBUG 47133 --- [           main] o.s.orm.jpa.JpaTransactionManager        : Committing JPA transaction on EntityManager [SessionImpl(1968179698<open>)]
2020-06-30 01:12:17.542 DEBUG 47133 --- [           main] o.s.orm.jpa.JpaTransactionManager        : Closing JPA EntityManager [SessionImpl(1968179698<open>)] after transaction