@Transactional을 SpringData와 함께 사용하는 방법?


82

방금 Spring-data, Hibernate, MySQL, JPA 프로젝트 작업을 시작했습니다. 수동으로 쿼리를 만드는 것에 대해 걱정할 필요가 없도록 스프링 데이터로 전환했습니다.

@Transactional주석없이 내 쿼리를 시도했기 때문에 스프링 데이터를 사용할 때 의 사용이 필요하지 않다는 것을 알았습니다 .

@Transactional주석을 사용하거나 사용하지 않아야하는 특별한 이유가 있습니까?

공장:

@Transactional
public List listStudentsBySchool(long id) {
    return repository.findByClasses_School_Id(id);
}

또한 작동합니다 :

public List listStudentsBySchool(long id) {
    return repository.findByClasses_School_Id(id);
}

미리 감사드립니다!

답변:


140

실제로 질문은 무엇입니까? 의 사용법 @Repository주석 또는 @Transactional.

@Repository선언 한 인터페이스는 스프링 데이터 인프라가 생성하고 어쨌든 예외 번역을 활성화하는 프록시에 의해 지원되므로 전혀 필요하지 않습니다. 따라서 SpringData 저장소 인터페이스에서이 주석을 사용하는 것은 전혀 효과가 없습니다.

@Transactional-JPA 모듈의 경우 프록시 ( SimpleJpaRepository)를 지원하는 구현 클래스에이 주석이 있습니다. 그 이유는 두 가지입니다. 첫째, 객체를 유지하고 삭제하려면 JPA에서 트랜잭션이 필요합니다. 따라서 트랜잭션이 실행 중인지 확인해야합니다.이 작업은 메서드에 @Transactional.

같은 방법을 읽기 findAll()findOne(…)사용 @Transactional(readOnly = true)을 엄격히 필요는 없지만 트랜잭션 인프라에 몇 가지 최적화를 트리거하는합니다 (이 설정 FlushModeMANUAL을 닫을 때 공급자가 잠재적으로 오염 검사를 건너 뛰 지속성 수 있도록 EntityManager). 그 외에도 플래그가 JDBC 연결에 설정되어 해당 수준에서 추가 최적화가 발생합니다.

사용하는 데이터베이스에 따라 테이블 잠금을 생략하거나 실수로 트리거 할 수있는 쓰기 작업을 거부 할 수도 있습니다. 따라서 @Transactional(readOnly = true)리포지토리 인터페이스에 해당 주석을 쉽게 추가 할 수있는 쿼리 메서드도 사용 하는 것이 좋습니다 . @Transactional해당 인터페이스에서 선언하거나 다시 장식했을 수있는 조작 메서드에 일반 을 추가해야합니다 .


8
간단히 말해서 추가 / 편집 / 삭제 쿼리에 @Transactional을 사용하고 모든 DAO 메서드에 대한 선택 쿼리에 @Transaction (readOnly = true)를 사용해야합니까?
Byron Voorbach

20
바로 그거죠. 이를 수행하는 가장 쉬운 방법 @Transactional(readOnly = true)은 인터페이스에서 사용 하고 (일반적으로 대부분 finder 메소드를 포함하므로) 일반 @Transactional. 그것이 실제로 SimpleJpaRepositoy.
Oliver Drotbohm

@Oliver는 포괄적 인 설명을 해주셔서 감사합니다. 그러나 다른 링크 [transaction-pit-falls] < ibm.com/developerworks/java/library/j-ts1/index.html#listing8 >을 살펴 보겠습니다 . 그것은 말한다 " 결론은 당신이 ORM 기반의 프레임 워크를 사용할 때, 읽기 전용 플래그를 무시 꽤 쓸모 대부분의 경우입니다.하지만 당신은 아직도 그것을 사용하여 주장하는 경우, 항상 SUPPORTS에 전파 모드를 설정한다는 것입니다 " . .이 글을 읽은 후 (readOnly = true)를 단독으로 사용해야하는지 확실하지 않습니다. 항상 전파 모드와 함께 SUPPORTS로 사용해야하는지 여부.
Anupam Gupta 2013

8
이 기사 섹션에서는 모든 것이 잘못되었습니다. 작성하지 않음을 표시함으로써 JDBC 구동은 DB 상호 작용의 성능을 향상시킬 수 있습니다. 또한 실수로 발행 된 쓰기를 감지하고 거부 할 수도 있습니다. 게다가 Spring은 읽기 전용 모드에서 JPA / Hibernate 플러싱을 비활성화하므로 공급자가 더티 검사를 수행 할 필요가 없기 때문에 큰 개체 그래프를 읽을 경우 성능에 큰 영향을 미칠 수 있습니다. 플래그는 거래 자체에 큰 영향을 미치지 않을 수도 있지만 고려할 모든 것이 아닙니다.
Oliver Drotbohm

큰 개체 그래프 또는 많은 수의 관리 개체를로드하는 사용 사례의 경우 성능 향상을 보증 할 수 있습니다.
Shailendra는

3

나는 질문이 조금 더 넓고 데이터 액세스 레이어의 주석에서 줄일 수 없다고 생각합니다. 애플리케이션의 전체 스택, 적용하려는 트랜잭션 전략 등을 고려해야합니다. IBM developerworks 사이트에 Mark Richards가이 주제에 대한 매우 포괄적 인 기사 세트가 있습니다. 첫 번째는 https://developer.ibm.com/articles/j-ts1/ 에서 찾을 수 있습니다.

친애하는


2

@Repository주석을 사용해야합니다.

이것은 @Repository확인되지 않은 SQL 예외를 Spring Excpetion으로 변환하는 데 사용되며 처리해야하는 유일한 예외는DataAccessException


10
이것은 일반적으로 Spring을 사용할 때 사실이지만 Spring Data 저장소는 이미 Spring 프록시에 의해 지원되기 때문에 @Repository를 사용하는 것은 아무런 차이가 없습니다.
Aleksander Blomskøld

0

또한 @Transactional 주석을 사용하여 다른 스레드 / 요청이 읽기를 변경하지 않도록 레코드를 잠급니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.