java Spring JPA 存储库事务性

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/39827054/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-11-03 04:40:35  来源:igfitidea点击:

Spring JPA repository transactionality

javajpaspring-dataspring-transactions

提问by FlasH from Ru

1 quick question on Spring JPA repositories transactionality. I have a service that is not marked as transactional and calls Spring JPA repository method

关于 Spring JPA 存储库事务性的 1 个快速问题。我有一个未标记为事务性的服务并调用 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 ordeleteByEmail(..)method as transactional, but I just can't understand why it crashes now. 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?

好的,我可以通过将服务deleteByEmail(..)方法标记为事务来解决它,但我不明白为什么它现在崩溃了。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

回答by Maciej Marczuk

You are right. Only CRUD methods (CrudRepositorymethods) are by default marked as transactional. If you are using custom query methods you should explicitly mark it with @Transactionalannotation.

你说的对。CrudRepository默认情况下,只有 CRUD 方法(方法)被标记为事务性的。如果您使用自定义查询方法,您应该使用@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/ JpaRepositoryimplementation - 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) {