Spring JPA存储库事务性

f45qwnt8  于 2023-03-19  发布在  Spring
关注(0)|答案(1)|浏览(151)

1个关于Spring JPA存储库事务性的快速问题。我有一个未标记为事务性的服务,它调用Spring JPA存储库方法

userRegistrationRepository.deleteByEmail(email);

它被定义为

@Repository
public interface UserRegistrationRepository extends JpaRepository<UserRegistration, Long> {

    UserRegistration findByEmail(String email);

    void deleteByEmail(String email);

}

问题是它失败了,并显示“* 当前线程没有具有实际事务的EntityManager-无法可靠地处理”remove“调用;嵌套异常是javax.persistence.TransactionRequiredException*”异常。
好吧,我可以通过将服务deleteByEmail(..) 方法标记为事务性来解决这个问题,但我就是不明白为什么它现在崩溃了。Spring文档明确指出“* 存储库示例上的CRUD方法默认情况下是事务性的。*”(http://docs.spring.io/spring-data/jpa/docs/current/reference/html/#transactions),但显然这一条不是...那么这条语句只与CrudRepository的成员相关吗?
ps:这是针对Spring Data JPA 1.9.4的

1dkrff03

1dkrff031#

您说得对。只有CRUD方法(CrudRepository方法)默认标记为事务性。如果您使用的是自定义查询方法,则应使用@Transactional注解显式标记。

@Repository
public interface UserRegistrationRepository extends JpaRepository<UserRegistration, Long> {

    UserRegistration findByEmail(String email);

    @Transactional
    void deleteByEmail(String email);

}

您还应了解标记资料档案库接口方法而不是服务方法的后果。如果使用的是默认事务传播配置(Propagation.REQUIRED),则:
存储库中的事务配置将被忽略,因为外部事务配置决定了实际使用的配置。
http://docs.spring.io/spring-data/jpa/docs/current/reference/html/#transactions
如果你想了解更多关于它是如何实现的信息,请查看默认的CrudRepository/JpaRepository实现-SimpleJpaRepository(你可能正在使用):
https://github.com/spring-projects/spring-data-jpa/blob/main/spring-data-jpa/src/main/java/org/springframework/data/jpa/repository/support/SimpleJpaRepository.java
有趣的台词如下:

@Transactional(readOnly = true)
public class SimpleJpaRepository<T, ID> implements JpaRepositoryImplementation<T, ID> {

和一些事务性方法:
一个二个一个一个

相关问题