Spring 및 JPA와의 트랜잭션

1. 개요

이 튜토리얼은 Spring Transactions를 구성하는 올바른 방법 , @Transactional 어노테이션 을 사용하는 방법 및 일반적인 함정에 대해 설명합니다.

핵심 지속성 구성에 대한보다 심층적 인 논의는 Spring with JPA 튜토리얼을 확인하십시오.

기본적으로 트랜잭션을 구성하는 두 가지 방법 (어노테이션과 AOP)이 있으며 각각 고유 한 장점이 있습니다. 여기서 더 일반적인 주석 구성에 대해 논의 할 것입니다.

2. 트랜잭션 구성

Spring 3.1 은 @Configuration 클래스 에서 사용할 수 있고 트랜잭션 지원을 활성화 할 수 있는 @EnableTransactionManagement 주석 을 도입 했습니다 .

@Configuration @EnableTransactionManagement public class PersistenceJPAConfig{ @Bean public LocalContainerEntityManagerFactoryBean entityManagerFactoryBean(){ //... } @Bean public PlatformTransactionManager transactionManager(){ JpaTransactionManager transactionManager = new JpaTransactionManager(); transactionManager.setEntityManagerFactory( entityManagerFactoryBean().getObject() ); return transactionManager; } }

그러나 Spring Boot 프로젝트를 사용하고 클래스 경로에 spring-data- * 또는 spring-tx 종속성이있는 경우 트랜잭션 관리가 기본적으로 활성화됩니다 .

3. XML로 트랜잭션 구성

3.1 이전 또는 Java가 옵션이 아닌 경우 주석 기반 및 네임 스페이스 지원을 사용하는 XML 구성은 다음 과 같습니다.

4. @Transactional 주석

트랜잭션이 구성된 상태에서 이제 클래스 또는 메서드 수준에서 @Transactional 로 빈을 주석 처리 할 수 ​​있습니다 .

@Service @Transactional public class FooService { //... }

주석은 추가 구성 도 지원합니다 .

  • 트랜잭션 의 전파 유형
  • 트랜잭션 의 격리 수준
  • 트랜잭션에 의해 래핑 된 작업에 대한 타임 아웃
  • 대한 읽기 전용 플래그 - 트랜잭션이 읽기 전용되어야한다는 지속성 공급자에 대한 힌트
  • 롤백 트랜잭션에 대한 규칙

기본적으로 롤백은 런타임에 대해 발생하며 확인되지 않은 예외에만 발생합니다. 확인 된 예외는 트랜잭션 의 롤백트리거하지 않습니다 . 물론 rollbackFornoRollbackFor 주석 매개 변수를 사용하여이 동작을 구성 할 수 있습니다 .

5. 잠재적 인 함정

5.1. 트랜잭션 및 프록시

높은 수준에서 Spring은 @Transactional로 주석이 달린 모든 클래스에 대한 프록시를 생성합니다 .-클래스 또는 모든 메소드에서. 프록시를 사용하면 프레임 워크가 주로 트랜잭션을 시작하고 커밋하기 위해 실행중인 메서드 전후에 트랜잭션 논리를 삽입 할 수 있습니다.

염두에 두어야 할 중요한 것은 트랜잭션 빈이 인터페이스를 구현하는 경우 기본적으로 프록시는 Java 동적 프록시가된다는 것입니다. 즉, 프록시를 통해 들어오는 외부 메서드 호출 만 차단됩니다. 자체 호출 호출은 메서드에 @Transactional 어노테이션 이 있더라도 트랜잭션을 시작하지 않습니다 .

프록시 사용에 대한 또 다른주의 사항은 공용 메서드 만 @Transactional 로 주석 처리해야한다는 것 입니다. 다른 가시성의 메소드는 프록시되지 않으므로 주석을 조용히 무시합니다.

이 기사는 여기에서 더 많은 프록시 함정에 대해 자세히 설명합니다.

5.2. 격리 수준 변경

트랜잭션 격리 수준을 변경할 수도 있습니다.

@Transactional(isolation = Isolation.SERIALIZABLE)

이것은 실제로 Spring 4.1에서 도입되었습니다. Spring 4.1 이전에 위의 예제를 실행하면 결과는 다음과 같습니다.

org.springframework.transaction.InvalidIsolationLevelException : 표준 JPA는 커스텀 격리 레벨을 지원하지 않습니다 – JPA 구현을 위해 특별한 JpaDialect 를 사용하세요.

5.3. 읽기 전용 트랜잭션

대한 읽기 전용 JPA로 작업 할 때 플래그는 일반적으로 특히, 혼란을 생성하고; Javadoc에서 :

이것은 실제 트랜잭션 하위 시스템에 대한 힌트 역할을합니다. 그것은 것입니다 필요는 없다 쓰기 액세스 시도의 실패 원인이됩니다. 읽기 전용 힌트를 해석 할 수없는 트랜잭션 관리자 는 읽기 전용 트랜잭션을 요청할 때 예외를 throw 하지 않습니다 .

사실은 readOnly 플래그가 설정 되었을 때 삽입 또는 업데이트가 발생하지 않을지 확신 할 수 없다는 것 입니다. 이 동작은 공급 업체에 따라 다르지만 JPA는 공급 업체에 구애받지 않습니다.

그것은 이해하는 것도 중요 대한 읽기 전용 플래그가 트랜잭션 내부에만 관련이 있습니다. 작업이 트랜잭션 컨텍스트 외부에서 발생하면 플래그는 무시됩니다. 간단한 예는 다음과 같이 주석이 달린 메소드를 호출합니다.

@Transactional( propagation = Propagation.SUPPORTS,readOnly = true )

비 트랜잭션 컨텍스트에서 – 트랜잭션이 생성되지 않고 readOnly 플래그가 무시됩니다.

5.4. 트랜잭션 로깅

트랜잭션 관련 문제를 이해하는 데 유용한 방법은 트랜잭션 패키지에서 로깅을 미세 조정하는 것입니다. Spring의 관련 패키지는“ org.springframework.transaction”이며, 로깅 수준을 TRACE로 구성해야합니다.

6. 결론

Java와 XML을 모두 사용하는 트랜잭션 의미 체계의 기본 구성, @Transactional 사용 방법 및 트랜잭션 전략의 모범 사례를 다루었습니다 .

항상 그렇듯이이 기사에 제시된 코드는 Github에서 사용할 수 있습니다.