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);
}
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
If you want more information about how it is implemented, take a look at default CrudRepository
/ JpaRepository
implementation - SimpleJpaRepository
(which you are probably using):
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) {
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…