Spring boot SpringBoot事务性传播需要';不创建新事务

Spring boot SpringBoot事务性传播需要';不创建新事务,spring-boot,hibernate,jpa,transactions,spring-transactions,Spring Boot,Hibernate,Jpa,Transactions,Spring Transactions,我有以下情况: @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(){

我有以下情况:

@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);
}
@服务
公共类服务{
@自动连线专用服务b服务b;
公共无效runA(){
serviceB.runB()
}
}
@服务
公共类服务B{
@自动连线专用服务;
@交易的
公共无效runB(){
serviceC.runC()
…其余的逻辑
}
}
@服务
公共类服务{
@自动连线专用测试库;
@事务性(传播=传播。需要\u新建)
公共布尔runC(){
Optional testEntityOptional=testRepository.findByKeyAndType(“Key”,“Type”);
if(testEntityOptional.isPresent()){
testEntityOptional.get().setActive(true);
返回true;
}
返回false;
}
}
@交易的
公共接口测试库
扩展JpaRepository、JpaSpecificationExecutor{
@锁(锁模式类型。悲观写入)
@QueryHints({@QueryHint(name=“javax.persistence.lock.timeout”,value=“5000”)})
可选findByKeyAndType(@NotNull字符串键,@NotNull字符串类型);
}
我预计下一个流程:

  • ServiceA.runA()
    调用
    ServiceB.runB()
  • ServiceB.runB()
    打开事务_1(或使用以前打开的事务),因为默认传播是
    必需的
  • ServiceB.runB()
    调用
    ServiceC.runC()
  • ServiceC.runC()
  • ServiceC.runC()
  • TestRepository.findByKeyAndType()
    从数据库返回符合条件的记录,并将其锁定以进行读取/更新
  • ServiceB.runC()
    处理记录
  • ServiceB.runC()
    返回值,事务2被提交,锁被释放
  • ServiceB.runB()
    返回并提交事务
  • 但从我的测试来看,情况并非如此。它表明
    ServiceC.runC()
    不创建新事务(事务\u 2),即使设置了传播
    REQUIRED\u new
    (或者在返回时不提交),锁也仅在
    ServiceB.runB()返回时释放(在提交事务\u 1时)

    有人知道我做错了什么吗?这是SpringBoot的正常行为吗

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


    所以它看起来像
    @QueryHints({@QueryHint(name=“javax.persistence.lock.timeout”,value=“5000”)})
    一旦记录被锁定就不能工作,另一个试图读取记录的事务会挂起一段时间,直到记录解锁为止。我启用了
    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
    
    2020-06-30 01:11:53.239调试47133---[main]o.s.orm.jpa.JpaTransactionManager:创建名为[com.example.accessingdatajpa.BlogService.save]的新事务:需要传播,默认隔离
    2020-06-30 01:11:57.532调试47133---[main]o.s.orm.jpa.JpaTransactionManager:为jpa事务打开了新的EntityManager[SessionImpl(1968179698)]
    2020-06-30 01:11:57.538调试47133---[main]o.s.orm.jpa.JpaTransactionManager:将jpa事务公开为JDBC[org.springframework.orm.jpa.vendor.HibernateJpaDialect$HibernateConnectionHandle@7f2542f]
    2020-06-30 01:12:02.432调试47133---[main]o.s.orm.jpa.JpaTransactionManager:为jpa事务找到了线程绑定的EntityManager[SessionImpl(1968179698)]
    2020-06-30 01:12:04.032调试47133---[main]o.s.orm.jpa.JpaTransactionManager:暂停当前事务,创建名为[com.example.accessingdatajpa.Service2.save]的新事务
    2020-06-30 01:12:06.915调试47133---[main]o.s.orm.jpa.JpaTransactionManager:为jpa事务打开了新的EntityManager[SessionImpl(2143659352)]
    2020-06-30 01:12:06.916调试47133---[main]o.s.orm.jpa.JpaTransactionManager:将jpa事务公开为JDBC[org.springframework.orm.jpa.vendor.HibernateJpaDialect$HibernateConnectionHandle@42fd8f2f]
    2020-06-30 01:12:10.196调试47133---[main]o.s.orm.jpa.JpaTransactionManager:为jpa事务找到了线程绑定的EntityManager[SessionImpl(2143659352)]
    2020-06-30 01:12:11.489调试47133---[main]o.s.orm.jpa.JpaTransactionManager:参与现有事务
    2020-06-30 01:12:12.227调试47133---[main]o.s.orm.jpa.JpaTransactionManager:启动事务提交
    2020-06-30 01:12:13.082调试47133---[main]o.s.orm.jpa.JpaTransactionManager:在EntityManager上提交jpa事务[SessionImpl(2143659352)]
    2020-06-30 01:12:13.109调试47133---[main]o.s.orm.jpa.JpaTransactionManager:事务处理后关闭jpa实体管理器[SessionImpl(2143659352)]
    2020-06-30 01:12:13.110调试47133---[main]o.s.orm.jpa.JpaTransactionManager:内部事务完成后恢复暂停的事务
    2020-06-30 01:12:16.409调试47133---[main]o.s.orm.jpa.JpaTransactionManager:启动事务提交
    2020-06-30 01:12:17.541调试47133---[main]o.s.orm.jpa.JpaTransactionManager:在EntityManager上提交jpa事务[SessionImpl(1968179698)]
    2020-06-30 01:12:17.542调试47133---[main]o.s.orm.jpa.JpaTransactionManager:事务处理后关闭jpa实体管理器[SessionImpl(1968179698)]
    
    一旦我启用了
    logging.level.org.springframework.orm.jpa.JpaTransactio