【问题标题】:SpringBoot Transactional Propagation REQUIRES_NEW doesn't create new TransactionSpringBoot 事务传播 REQUIRES_NEW 不会创建新事务
【发布时间】:2020-10-20 04:36:41
【问题描述】:

我有以下场景:

@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);
}

我期待下一个流程:

  1. ServiceA.runA() 调用 ServiceB.runB()
  2. ServiceB.runB() 打开 TRANSACTION_1(如果之前打开过,则使用事务),因为默认传播是 REQUIRED
  3. ServiceB.runB() 调用 ServiceC.runC()
  4. ServiceC.runC() 打开 TRANSACTION_2 因为传播是 REQUIRED_NEW
  5. ServiceC.runC() 调用 TestRepository.findByKeyAndType() 按某些条件获取 testEntity
  6. TestRepository.findByKeyAndType() 从数据库返回符合条件的记录并将其锁定以供读取/更新
  7. ServiceB.runC()处理记录
  8. ServiceB.runC() 返回值并提交 TRANSACTION_2 并释放锁
  9. ServiceB.runB() 返回并提交 TRANSACTION_1

但根据我的测试,情况并非如此。它接缝ServiceC.runC() 不创建新事务(TRANSACTION_2),即使设置了传播REQUIRED_NEW(或者它在返回时不提交它),并且仅当ServiceB.runB() 返回时才释放锁定(当提交TRANSACTION_1 时)

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

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

所以看起来@QueryHints({@QueryHint(name = "javax.persistence.lock.timeout", value = "5000")}) 不起作用,因为一旦记录被锁定,另一个尝试读取记录的事务会挂起一段时间,直到记录被解锁

【问题讨论】:

  • 感谢您记录财产。我只是调试并 100% 确定没有打开新事务

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


【解决方案1】:

启用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

【讨论】:

    猜你喜欢
    • 2016-07-23
    • 2016-11-16
    • 1970-01-01
    • 2012-09-05
    • 1970-01-01
    • 2012-10-14
    • 2023-03-03
    • 2012-09-25
    • 1970-01-01
    相关资源
    最近更新 更多