简体   繁体   English

Spring JPA存储库事务性

[英]Spring JPA repository transactionality

1 quick question on Spring JPA repositories transactionality. 关于Spring JPA存储库事务性的1个快速问题。 I have a service that is not marked as transactional and calls Spring JPA repository method 我有一个未标记为事务性的服务,并调用Spring JPA存储库方法

userRegistrationRepository.deleteByEmail(email);

And it is defined as 它被定义为

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

    UserRegistration findByEmail(String email);

    void deleteByEmail(String email);

}

The problem is that it fails with " No EntityManager with actual transaction available for current thread - cannot reliably process 'remove' call; nested exception is javax.persistence.TransactionRequiredException " exception. 问题是它失败了“ 没有实体事务可用于当前线程的EntityManager - 无法可靠地处理'删除'调用;嵌套异常是javax.persistence.TransactionRequiredException ”异常。

Ok, I can solve it by marking the service or deleteByEmail(..) method as transactional, but I just can't understand why it crashes now. 好吧,我可以通过将服务 deleteByEmail(..)方法标记为事务来解决它,但我无法理解为什么它现在崩溃。 Spring documentation explicitly states that " CRUD methods on repository instances are transactional by default. " ( http://docs.spring.io/spring-data/jpa/docs/current/reference/html/#transactions ), but apparently this one is not... So Is this statement related to only members of CrudRepository ? Spring文档明确声明“ 默认情况下,存储库实例上的CRUD方法是事务性的。 ”( http://docs.spring.io/spring-data/jpa/docs/current/reference/html/#transactions ),但显然这个不是......那么这个陈述只与CrudRepository成员有关吗?

ps: that's for Spring Data JPA 1.9.4 ps:那是Spring Data JPA 1.9.4

You are right. 你是对的。 Only CRUD methods ( CrudRepository methods) are by default marked as transactional. 默认情况下,只有CRUD方法( CrudRepository方法)标记为事务性方法。 If you are using custom query methods you should explicitly mark it with @Transactional annotation. 如果您使用自定义查询方法,则应使用@Transactional注释明确标记它。

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

    UserRegistration findByEmail(String email);

    @Transactional
    void deleteByEmail(String email);

}

You should also be aware about consequences of marking repository interface methods instead of service methods. 您还应该了解标记存储库接口方法而不是服务方法的后果。 If you are using default transaction propagation configuration ( Propagation.REQUIRED ) then: 如果您使用默认事务传播配置( Propagation.REQUIRED ),那么:

The transaction configuration at the repositories will be neglected then as the outer transaction configuration determines the actual one used. 由于外部事务配置确定使用的实际配置,因此将忽略存储库中的事务配置。

http://docs.spring.io/spring-data/jpa/docs/current/reference/html/#transactions http://docs.spring.io/spring-data/jpa/docs/current/reference/html/#transactions

If you want more information about how it is implemented, take a look at default CrudRepository / JpaRepository implementation - SimpleJpaRepository (which you are probably using): 如果您想了解有关它的实现方式的更多信息,请查看默认的CrudRepository / JpaRepository实现 - SimpleJpaRepository (您可能正在使用它):

https://github.com/spring-projects/spring-data-jpa/blob/master/src/main/java/org/springframework/data/jpa/repository/support/SimpleJpaRepository.java https://github.com/spring-projects/spring-data-jpa/blob/master/src/main/java/org/springframework/data/jpa/repository/support/SimpleJpaRepository.java

The interesting lines are here: 有趣的线条在这里:

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

and some of transactional methods here: 以及一些交易方法:

@Transactional
public void deleteById(ID id) {
@Transactional
public <S extends T> S save(S entity) {

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM