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
Spring JPA repository transactionality
提问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 (CrudRepository
methods) are by default marked as transactional.
If you are using custom query methods you should explicitly mark it with @Transactional
annotation.
你说的对。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
/ JpaRepository
implementation - SimpleJpaRepository
(which you are probably using):
如果您想了解有关它如何实现的更多信息,请查看默认CrudRepository
/JpaRepository
实现 - SimpleJpaRepository
(您可能正在使用):
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) {