Spring @Transactional 不适用于@NoRepository 层次结构

Spring @Transactional not working with @NoRepository hierarchy

我有一个基本接口来承包自定义更新的查询。这是一个在其他 spring 应用程序中使用的库,在某些环境中,我有一个辅助“transactionManager”和一个辅助“entityManager”。如果此辅助事务管理器存在于 spring 上下文中,我的存储库必须使用它。

下面是这个基本存储库接口的代码:

@NoRepository
interface MyEntityRepository extends JpaRepository<MyEntity, Integer> {

   @Query("update ....")
   @Modifying
   void updateSomething();

}

我还有另外两个接口要用条件定义:

@Repository("myEntityRepository")
@Transactional(transactionManager = "sharedTransactionManager")
@ConditionalOnBean(name = "sharedTransactionManager")
interface SharedMyEntityRepository extends MyEntityRepository {
}

@Repository("myEntityRepository")
@Transactional
@ConditionalOnMissingBean(name = "sharedTransactionManager")
interface DefaultMyEntityRepository extends MyEntityRepository {
}

但是当我 运行 MyEntityRepository.updateSomething 方法时,我收到了这个错误:

org.springframework.dao.InvalidDataAccessApiUsageException: no transaction is in progress; nested exception is javax.persistence.TransactionRequiredException: no transaction is in progress

我该如何解决这个问题?为什么 spring 不应用基于两个 @Repository(SharedMyEntityRepository 或 DefaultMyEntityRepository)的事务?

因为@Transactional 不能向后工作,它可以传播到 subclass 而不是相反,你要么重新定义 subclass 中的方法,要么添加 @Transactional在父 class 或方法本身上。

经过一些测试,我让它工作了。

我只需要在基本接口方法中收缩@Transactional(没有任何transactionManager)。之后,在子存储库中,我不得不通过 @Transactional(transactionManager = "sharedTransactionManager").

在我的最终界面上签订新的 transactionManager

代码如下:

@NoRepository
interface MyEntityRepository extends JpaRepository<MyEntity, Integer> {

   @Transactional // this contracts the base method as transactional
   @Query("update ....")
   @Modifying
   void updateSomething();

}

@Repository("myEntityRepository")
@Transactional(transactionManager = "sharedTransactionManager") // override the transactionManager
@ConditionalOnBean(name = "sharedTransactionManager")
interface SharedMyEntityRepository extends MyEntityRepository {
}

@Repository("myEntityRepository")
@ConditionalOnMissingBean(name = "sharedTransactionManager")
interface DefaultMyEntityRepository extends MyEntityRepository {
}

因此,当 SharedMyEntityRepository.updateSomething 运行时,它使用通过接口级别注释约定的 sharedTransactionManager 启动事务。