簡體   English   中英

Spring JPA存儲庫事務性

[英]Spring JPA repository transactionality

關於Spring JPA存儲庫事務性的1個快速問題。 我有一個未標記為事務性的服務,並調用Spring JPA存儲庫方法

userRegistrationRepository.deleteByEmail(email);

它被定義為

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

    UserRegistration findByEmail(String email);

    void deleteByEmail(String email);

}

問題是它失敗了“ 沒有實體事務可用於當前線程的EntityManager - 無法可靠地處理'刪除'調用;嵌套異常是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

你是對的。 默認情況下,只有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/master/src/main/java/org/springframework/data/jpa/repository/support/SimpleJpaRepository.java

有趣的線條在這里:

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

以及一些交易方法:

@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