Skip to content

Latest commit

 

History

History
92 lines (52 loc) · 5.85 KB

트랜잭션.md

File metadata and controls

92 lines (52 loc) · 5.85 KB

포괄적인 트랜잭션 지원은 Spring Framework를 사용하는 가장 강력한 이유 중 하나이다. Spring Framework는 다음과 같은 이점을 제공하는 트랜잭션 관리를 위한 일관된 추상화를 제공한다.

  • JTA(Java Transaction API), JDBC, Hibernate 및 JPA(Java Persistence API)와 같은 다양한 트랜잭션 API에서 일관된 프로그래밍 모델
  • 선언적 트랜잭션 관리 지원
  • 프로그래밍 방식 트랜잭션 관리 지원
  • Spring의 데이터 접근 추상화와의 뛰어난 통합

이전의 Transaction 지원 모델......

Spring Transaction 지원 모델에 대해 알아보기 전에, 이전의 Transaction 처리 방식에 대해 알아보자.

전통적인 Java EE 개발자는 트랜잭션 관리를 하기 위해선 두가지중 하나를 선택해야했다.

  • Global Transactions
  • Local Transactions

Global Transactions

  • Global Transactions는 RDB나 MQ 등의 여러 리소스에서 작업할 수 있는 통용되는 트랜잭션 관리 방법이다. 주로 JTA를 통해 글로벌 트랜잭션을 관리한다. 또한 JTA의 UserTransaction은 일반적으로 JNDI에서 제공되어야 한다. 즉, JTA를 사용하려면 JNDI도 사용해야 한다.

  • JTA는 일반적으로 응용 프로그램 서버 환경에서만 사용할 수 있으므로 전역 트랜잭션을 사용하면 응용 프로그램 코드의 잠재적인 재사용이 제한된다. 그렇기 때문에 JTA는 햔재 잘 쓰이지 않는 기술이다.

  • 이전에 Global Transactions를 사용하는데 선호되었던 방법은 EJB CMT (Container Managed Transaction)였다. CMT는 선언적 트랜잭션 관리의 한 형태인데, 이 CMT는 JTA 및 응용 프로그램 서버 환경에 묶여 있어 EJB와 꼭 함께 사용해야만 한다.

하지만 EJB는 너무나도 많은 단점을 가지고 있기 때문에, 현재는 CMT 또한 잘 쓰이지 않는다.

Local Transactions

  • Local Transactions는 각 데이터나 기술에 맞는 트랜잭션 방식을 사용하는 것이다. 각 기술에 특화되어있기 때문에 그에 따라 코드를 다 따로 작성해줘야한다. 또, 애플리케이션 서버는 트랜잭션 관리에 관여하지 않기 때문에 여러 리소스에 대한 정확성을 보장하는 데 도움이 되지 않는다.

Spring Transaction 지원 모델

  • Spring은 Global Transactions와 Local Transactions의 문제를 해결한다! Spring은 개발자가 개발 환경에 구애받지 않고 일관된 프로그래밍 모델을 사용할 수 있도록 해준다.

  • 프로그래밍 방식의 트랜잭션 관리를 통해 개발자는 기본 트랜잭션 인프라에서, 실행할 수 있는 Spring 트랜잭션 추상화로 작업할 수 있다. 트랜잭션 관리라는 구체적인 부분과 다른 로직이 구분되기 때문에 DIP적이다.

  • Spring Framework는 선언적 트랜잭션 관리와 프로그래밍 트랜잭션 관리를 모두 제공하며, 대부분의 경우에는 선언적 트랜잭션 관리가 선호된다.


Spring Framework가 트랜잭션을 추상화하는 방식

Spring 트랜잭션 추상화에서 가장 중요한 것은, 트랜잭션 전략이라는 개념이다.

이 트랜잭션 전략은 TransactionManager에 의해 정의된다.

트랜잭션 전략중 주로 쓰이는 것은, PlatformTransactionManager 인터페이스가 있다. 인터페이스이기 때문에 상황에 따라 맞는 구현체를 선택할 수 있다.

public interface TransactionManager {
}

public interface PlatformTransactionManager extends TransactionManager {

    TransactionStatus getTransaction(TransactionDefinition definition) throws TransactionException;

    void commit(TransactionStatus status) throws TransactionException;

    void rollback(TransactionStatus status) throws TransactionException;
}

여기서 getTransaction(...) 메소드는 TransactionDefinition을 파라미터로 받아 TransactionStatus를 반환한다.

TransactionStatus는 새 트랜잭션, 혹은 현재 쓰레드에 이미 존재하는 트랜잭션의 정보를 나타내며, TransactionDefinition 인터페이스는 트랜잭션의 다양한 속성을 지정할 수 있다.

TransactionDefinition에서 지정할 수 있는 속성으로는 다음과 같은 것들이 있다.

  • 전파 : 트랜잭션 범위 안에 있는 모든 코드는 트랜잭션에 묶여 실행된다. 하지만 트랜잭션 컨텍스트가 이미 존재할 때는 트랜잭션 메소드가 동작하는 방식을 따로 지정할 수 있다.

    일반적인 경우에는 코드가 기존 트랜잭션에서 계속 실행되지만, 원하는 경우에는 기존 트랜잭션을 일시 중단하고 새 트랜잭션을 생성할 수 있다. 트랜잭션 전파 문서에서 더 알아보자

  • 격리수준 : 트랜잭션이 다른 트랜잭션의 작업과 격리되는 정도이다. READ_UNCOMMITTED, READ_COMMITTED, READ_COMMITTED, SERIALIZABLE 등의 설정값이 있다. 또는, RDBMS의 기본값에 따를 수도 있다.

  • 시간 제한 : 트랜잭션이 일정 시간 이상 수행되면, 자동으로 롤백되도록 설정할 수 있다.

  • 읽기 전용 여부 : 트랜잭션을 Read-Only로 설정하여 일부 기능을 최적화할 수 있다. Hibernate를 사용하는 경우에 유용하게 사용될 수 있다.

이러한 설정은 표준 트랜잭션 개념을 반영한다. 트랜잭션에 대해 자세히 알고 싶다면 이 문서를 참조할 수 있다.


출처: https://docs.spring.io/spring-framework/docs/current/reference/html/data-access.html#transaction