我有以下情况:
product
我希望下一个流程:
@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()
ServiceB.runB()
打开TRANSACTION_1(或使用事务,如果之前已打开),因为默认传播为ServiceB.runB()
REQUIRED
调用ServiceB.runB()
ServiceC.runC()
打开TRANSACTION_2,因为传播是ServiceC.runC()
REQUIRED_NEW
调用ServiceC.runC()
以根据某些条件获取testEntity TestRepository.findByKeyAndType()
从数据库返回符合条件的记录,并将其锁定以进行读取/更新TestRepository.findByKeyAndType()
处理记录ServiceB.runC()
返回值,并且TRANSACTION_2已提交,因此锁已释放ServiceB.runC()
返回并提交TRANSACTION_1 但是从我的测试来看并非如此。它表明ServiceB.runB()
即使设置了传播ServiceC.runC()
也不会创建新事务(TRANSACTION_2)(或者它不会在返回时提交它),并且仅在REQUIRED_NEW
返回时释放锁定(提交TRANSACTION_1时)
有人在这里看到我在做什么错吗?这是SpringBoot的正常行为吗?
另外,锁定超时不起作用: 我正在使用Postgress v10 for DB,其中lock_timeout设置为“ 0”。
因此,ServiceB.runB()
似乎无法工作,因为一旦记录被锁定,其他尝试读取记录的事务将挂起一段时间,直到记录被解锁
答案 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