Spring JPA 存储库事务性 [英] Spring JPA repository transactionality
问题描述
关于 Spring JPA 存储库事务性的 1 个快速问题.我有一个未标记为事务性的服务并调用 Spring JPA 存储库方法
1 quick question on Spring JPA repositories transactionality. I have a service that is not marked as transactional and calls Spring JPA repository method
userRegistrationRepository.deleteByEmail(email);
定义为
@Repository
public interface UserRegistrationRepository extends JpaRepository<UserRegistration, Long> {
UserRegistration findByEmail(String email);
void deleteByEmail(String email);
}
问题在于它因没有 EntityManager 与当前线程可用的实际事务 - 无法可靠地处理‘删除’调用;嵌套异常是 javax.persistence.TransactionRequiredException"异常而失败.
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.
好的,我可以通过将服务或deleteByEmail(..)标记为事务性来解决它,但我不明白为什么它现在崩溃了.Spring 文档明确指出存储库实例上的 CRUD 方法默认是事务性的."(http://docs.spring.io/spring-data/jpa/docs/current/reference/html/#transactions),但显然这是不是... 那么这个声明是否只与 CrudRepository
的成员有关?
Ok, I can solve it by marking the service or deleteByEmail(..) 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
?
ps:适用于 Spring Data JPA 1.9.4
ps: that's for Spring Data JPA 1.9.4
推荐答案
你说得对.默认情况下,只有 CRUD 方法(CrudRepository
方法)被标记为事务性的.如果您使用自定义查询方法,您应该使用 @Transactional
注释显式标记它.
You are right. Only CRUD methods (CrudRepository
methods) are by default marked as transactional.
If you are using custom query methods you should explicitly mark it with @Transactional
annotation.
@Repository
public interface UserRegistrationRepository extends JpaRepository<UserRegistration, Long> {
UserRegistration findByEmail(String email);
@Transactional
void deleteByEmail(String email);
}
您还应该了解标记存储库接口方法而不是服务方法的后果.如果您使用默认事务传播配置 (Propagation.REQUIRED
),则:
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:
存储库中的事务配置将被忽略然后作为外部事务配置确定实际的用过.
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
如果您想了解更多关于它是如何实现的信息,请查看默认的 CrudRepository
/JpaRepository
实现 - SimpleJpaRepository
(您是可能正在使用):
If you want more information about how it is implemented, take a look at default CrudRepository
/ JpaRepository
implementation - SimpleJpaRepository
(which you are probably using):
有趣的台词在这里:
@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) {
这篇关于Spring JPA 存储库事务性的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!