struts로 검색한 결과 :: 시소커뮤니티[SSISO Community]
 
SSISO 카페 SSISO Source SSISO 구직 SSISO 쇼핑몰 SSISO 맛집
추천검색어 : JUnit   Log4j   ajax   spring   struts   struts-config.xml   Synchronized   책정보   Ajax 마스터하기   우측부분

회원가입 I 비밀번호 찾기


SSISO Community검색
SSISO Community메뉴
[카페목록보기]
[블로그등록하기]  
[블로그리스트]  
SSISO Community카페
블로그 카테고리
정치 경제
문화 칼럼
비디오게임 스포츠
핫이슈 TV
포토 온라인게임
PC게임 에뮬게임
라이프 사람들
유머 만화애니
방송 1
1 1
1 1
1 1
1 1
1

struts로 검색한 결과
등록일:2008-06-03 13:27:57
작성자:
제목:Spring에서 트랜잭션 일시 중지 구현


Spring에서 트랜잭션 일시 중지 구현

by Juergen Hoeller
2005/07/04

개요

널리 사용되고 있는 Java/J2EE 애플리케이션 프레임워크로서 lightweight Inversion-of-Control 컨테이너에서 구축된 Spring Framework는 특히 데이터 액세스와 트랜잭션 관리 기능으로 잘 알려져 있습니다. EJB CMT(Container-Managed Transactions)에서와 같은 정교한 선언적 트랜잭션과 함께 어떠한 POJO 대상 객체에도 Spring의 선언적 트랜잭션 경계 설정(demarcation)을 적용할 수 있습니다. 백엔드 트랜잭션 매니저에 대한 선택 범위는 단순한 JDBC 기반 트랜잭션으로부터 JTA를 통한 완전한 J2EE트랜잭션에 이르기까지 다양합니다.

이 문서에서는 Spring의 트랜잭션 관리 기능에 대해 자세히 다루도록 하겠습니다. JTA를 백엔드 트랜잭션 전략으로 하여 POJO에 대한 Spring의 선언적 트랜잭션을 이용하는 내용을 중점적으로 설명할 것입니다. 또한 Spring의 트랜잭션 서비스가 J2EE 서버의 트랜잭션 코디네이터(예: EJB CMT의 전형적인 트랜잭션 경계 설정 방식에 대한 대안으로 사용되는 BEA WebLogic Server용 트랜잭션 코디네이터)와 완벽하게 연동됨을 보여줄 것입니다.

POJO에 대한 선언적 트랜잭션

Spring의 선언적 트랜잭션 경계 설정 방식의 예로서 Spring PetClinic 샘플 애플리케이션의 중앙 서비스 facade에 대한 구성을 살펴보겠습니다.

<bean id="dataSource" 
   class="org.springframework.jndi.JndiObjectFactoryBean">
     <property name="jndiName">
        <value>java:comp/env/jdbc/petclinic</value>
     </property>
</bean>

<bean id="transactionManager" 
   class="org.springframework.transaction.jta.JtaTransactionManager"/>

<bean id="clinicTarget" 
   class="org.springframework.samples.petclinic.jdbc.JdbcClinic">
    <property name="dataSource"><ref bean="dataSource"/></property>
</bean>

<bean id="clinic" 
   class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">
    <property name="transactionManager"><ref bean="transactionManager"/></property>
    <property name="target"><ref bean="clinicTarget"/></property>
    <property name="transactionAttributes">
        <props>
            <prop key="load*">PROPAGATION_REQUIRED,readOnly</prop>
            <prop key="store*">PROPAGATION_REQUIRED</prop>
        </props>
    </property>
</bean>

이는 Spring의 표준 XMLBean 정의 형식을 따르며 다음의 내용을 정의합니다.

  • JNDI 위치를 가리키는 Datasource 참조 - J2EE 서버에서 관리하는JNDI 환경에서 지정된 DataSource를 페치합니다.
  • PlatformTransactionManager 구현 - 이 경우 구현 시 Spring의 JtaTransactionManager가 지정되며, J2EE 서버의 트랜잭션 코디네이터로 위임됩니다.
  • 애플리케이션 서비스 구현 - 이는 비즈니스와 데이터 접근 로직이 포함된 일반 POJO입니다. 이는 애플리케이션의 Clinic 서비스 인터페이스를 구현합니다.
  • 애플리케이션 서비스를 위한 트랜잭션 프록시 - 이 프록시는 대상 서비스에 대한 트랜잭션 속성을 정의하여 특정 메서드 이름 패턴을 부여하고 상응하는 트랜잭션을 생성합니다. 실질적인 트랜잭션 관리를 위해 프록시는 PlatformTransactionManager 구현을 가리킵니다.

참고: 명시적 프록시 정의의 대안으로서 Spring은 자동 프록시(auto-proxying) 메커니즘과 Commons Attributes 또는 J2SE 5.0 주석을 통한 소스 수준(source-level ) 메타데이터의 사용을 지원합니다. 이런 대안에 관한 논의는 이 문서의 취지를 벗어나는 것이니, 자세한 사항은 Spring 문서를 참조하십시오.

사용된 서비스 인터페이스와 서비스 구현은 애플리케이션에 따라 다르며 Spring이나 Spring 트랜잭션 관리에 대한 특별한 지식 없이도 구현할 수 있습니다. 일반 Java객체도 대상 객체가 될 수 있으며 어떤 일반 Java 인터페이스도 서비스 인터페이스가 될 수 있습니다. 다음은 Clinic 인터페이스의 예입니다.

public interface Clinic {
    Pet loadPet(int id);
    void storePet(Pet pet);
    ...
}

이 인터페이스의 간단한 구현 방법은 아래와 같으며, 여기서는 필요한 데이터에 액세스하기 위해 JDBC를 사용한다고 가정하였습니다. 빈 속성 설정자(bean property setter)를 통해 JDBC DataSource가 수신되는데, 이는 위에서 설정한 dataSource 속성 정의에 직접 대응됩니다.

public class JdbcClinic implements Clinic {

    private DataSource dataSource;

    public void setDataSource(DataSource dataSource) {
      this.dataSource = dataSource;
    }

    public Pet loadPet(int id) {
      try {
          Connection con = this.dataSource.getConnection();
          ...
      }
      catch (SQLException ex) {
        ...
      }
    }

    public void storePet(Pet pet) {
      try {
          Connection con = this.dataSource.getConnection();
          ...
      }
      catch (SQLException ex) {
        ...
      }
    }

    ...
}

이처럼 코드는 매우 단순하며 간단한 Java 객체가 사용됩니다. 트랜잭션은 다음에 설명할 트랜잭션 프록시에 의해 관리됩니다.

PetClinic 샘플 애플리케이션에서 실제로 JDBC 기반의 Clinic을 구현할 경우 Spring의 JDBC 지원 클래스를 이용함으로써 일반 JDBC API 수준에서의 작업을 피할 수 있습니다. 그러나 Spring의 트랜잭션 관리는 위에서 설명했듯이 일반 JDBC 기반의 구현과도 작동합니다.

트랜잭션 프록시 정의

code>JdbcClinic 인스턴스 외에도 구성을 통해 트랜잭션 프록시를 정의할 수 있습니다. 필요할 경우 이 프록시에 의해 노출되는 실제 인터페이스를 명시적으로 지정할 수 있습니다. 기본적으로 대상 객체에 의해 구현되는 모든 인터페이스(이 경우 애플리케이션의 Clinic 서비스 인터페이스)는 노출됩니다.

클라이언트의 관점에서 볼 때 "clinic" 빈은 애플리케이션의 Clinic 인터페이스 구현과 같습니다. 클라이언트는 이러한 작업이 트랜잭션 프록시를 통해 처리되고 있음을 알 필요가 없습니다. 이것이 인터페이스의 강점입니다. 대상 객체에 대한 직접적인 참조는 동일한 인터페이스를 구현하는 프록시(이 경우 암시적으로 트랜잭션을 생성하는 프록시)로 쉽게 대체할 수 있습니다.

프록시의 구체적인 트랜잭션 동작은 특정 메서드나 메서드 이름 패턴에 대한 트랜잭션 속성에 의해 수행됩니다. 아래의 예를 보십시오.

<prop key="load*">PROPAGATION_REQUIRED,readOnly</prop>
<prop key="store*">PROPAGATION_REQUIRED</prop>

key 속성은 프록시에 의해 추가된 트랜잭션 동작을 어떤 메서드에 할당할지 결정합니다. 그러한 속성의 가장 중요한 부분이 전달 동작(propagation behavior)입니다. 다음과 같은 옵션을 사용할 수 있습니다.

  • PROPAGATION_REQUIRED - 현재의 트랜잭션을 지원하고, 없을 경우 새로 만듭니다. 이것은 가장 자주 사용되는 옵션입니다.
  • PROPAGATION_SUPPORTS - 현재의 트랜잭션을 지원하고, 없을 경우 트랜잭션을 실행하지 않습니다.
  • PROPAGATION_MANDATORY - 현재의 트랜잭션을 지원하고, 없을 경우 예외를 throw합니다.
  • PROPAGATION_REQUIRES_NEW - 새로운 트랜잭션을 만들고 현재의 트랜잭션이 존재하면 이를 일시 중지합니다.
  • PROPAGATION_NOT_SUPPORTED - 트랜잭션을 실행하지 않다가 트랜잭션이 존재하게 되면 이를 일시 중지합니다.
  • PROPAGATION_NEVER - 트랜잭션을 실행하지 않다가 트랜잭션이 존재하게 되면 예외를 throw합니다.
  • PROPAGATION_NESTED - 현재의 트랜잭션이 존재하면 중첩된 트랜잭션 내에서 실행하고 존재하지 않으면 PROPAGATION_REQUIRED처럼 작동합니다.

처음 여섯 개 전략은 같은 상수 이름을 가지고 있는 EJB CMT와 비슷하기 때문에 EJB 개발자에게 무척 익숙할 것입니다. 일곱 번째 PROPAGATION_NESTED는 Spring에서 제공하는 특수한 variant입니다. 여기에는 중첩된 트랜잭션 동작(예: Spring의 DataSourceTransactionManager)을 제공하기 위해 JDBC 3.0 Savepoint API와 함께 작동하거나 JTA를 통해 중첩된 트랜잭션을 지원하는 트랜잭션 매니저가 필요합니다.

트랜잭션 속성의 readOnly 플래그는 상응하는 트랜잭션이 읽기 전용 트랜잭션으로 최적화되어야 한다는 것을 나타내는, 일종의 최적화 힌트입니다. 어떤 트랜잭션 전략은 중요한 최적화를 수행할 수 있는데, 예를 들어 Hibernate나 TopLink 같은 객체/관계 매핑 도구를 사용할 때 dirty checking("flush" 시도)을 회피하는 경우를 들 수 있습니다.

또한 트랜잭션 속성에서 "timeout" 값을 초 단위로 지정할 수 있는 옵션이 있습니다. JTA의 경우 이 작업이 J2EE 서버 트랜잭션 코디네이터로 넘겨지며 거기에서 적절히 해석됩니다.

트랜잭션 프록시로 작업

런타임 시, 클라이언트는 "clinic" 빈에 대한 참조를 페치하여 이를 Clinic 인터페이스로 전달하고 loadPet 이나 storePet과 같은 작업을 호출합니다. 이는 대상 객체 앞에 등록된 "트랜잭션 인터셉터"와 함께 암시적으로 Spring의 트랜잭션 프록시 전 과정을 거치게 됩니다. 그런 다음 새로운 트랜잭션이 생성되면 JdbcClinic 대상 메서드에게 호출이 위임됩니다.

그림 1은 "advisor chain" 및 마지막 대상이 포함된 AOP 프록시의 기본 개념을 보여줍니다. 이 경우, 유일한 advisor는 대상 메서드 주위로 트랜잭션 동작을 래핑(wrap)하는 트랜잭션 인터셉터 뿐입니다. 이것이 Spring의 선언적 트랜잭션 기능 아래에서 작동하는 프록시 기반의AOP(Aspect-Oriented Programming)입니다.

Figure 1
그림 1. advisor chain 및 마지막에 대상이 포함된 AOP 프록시

예를 들어 PetClinic 웹 애플리케이션의 웹 계층 컴포넌트는 ServletContext 조회를 수행하여, Spring의 WebApplicationContext 에 대한 참조를 얻은 다음 거기서 관리되는 "clinic" 빈에 대한 참조를 얻습니다.

WebApplicationContext ctx = 
   WebApplicationContexUtils.getWebApplicationContext(servletContext);
Clinic clinic = (Clinic) ctx.getBean("clinic);

Pet pet = new Pet();
pet.setName("my new cat");

clinic.storePet(pet);

storePet() 호출의 시작 부분에서 Spring의 트랜잭션 프록시는 암시적으로 트랜잭션을 생성합니다. storePet() 호출이 리턴될 때 트랜잭션은 커밋되거나 롤백됩니다. 기본적으로 RuntimeException이나 Error thrown은 롤백을 유도합니다. 커밋과 롤백에 대한 실제 규칙을 지정할 수 있습니다. Spring의 트랜잭션 속성은 "롤백 규칙"이라고 하는 개념을 지원합니다.

예를 들어, 확인된 PetClinicException 지정하고, 예외가 throw될 경우 트랜잭션 프록시에서 롤백하도록 지시할 수 있습니다.

<prop key="load*">PROPAGATION_REQUIRED,readOnly,-PetClinicException</prop>
<prop key="store*">PROPAGATION_REQUIRED,-PetClinicException</prop>

또한 "commit rules,"과 유사한 구문도 있는데, 이는 커밋을 트리거하도록 하는 특별한 예외의 경우를 나타냅니다.

위에서 설명한 명시적 조회는 Spring 관리 빈에 액세스하기 위한 일반적인 variant로서, 서블릿이나 필터와 같은 모든 웹 리소스와 함께 작동합니다. Spring 자체의 웹 MVC 프레임워크로 웹 계층을 구축할 경우 이러한 빈을 웹 컨트롤러에 직접 삽입할 수 있습니다. struts, WebWork, JSF, Tapestry에서도 Spring 빈으로 편리하게 액세스할 수 있습니다. 자세한 내용은 Spring 문서를 참조하십시오.

PlatformTransactionManager 전략

Spring의 트랜잭션 지원을 위한 핵심 인터페이스는 org.springframework.transaction.PlatformTransactionManager입니다. 실제로 트랜잭션을 수행하고 적절한 TransactionDefinition 인스턴스로 전달할 수 있도록 Spring의 모든 트랜잭션 경계 설정 기능은 PlatformTransactionManager로 위임됩니다. PlatformTransactionManager 인터페이스가 직접 사용될 수도 있지만, 보통 애플리케이션에서는 트랜잭션 경계 설정을 위해 단지 구체적인 트랜잭션 매니저를 구성하고 선언적 트랜잭션을 사용합니다.

Spring에서는 PlatformTransactionManager를 다양하게 구현할 수 있는데, 이는 다음의 두 범주로 분류됩니다.

  • 로컬 트랜잭션 전략 - 단일 리소스(대부분의 경우 단일 데이터베이스)에 대해 트랜잭션 실행. 예: org.springframework.jdbc.datasource.DataSourceTransactionManagerorg.springframework.orm.hibernate.HibernateTransactionManager.
  • 글로벌 트랜잭션 관리 - 여러 리소스로 확장될 수 있는 글로벌 트랜잭션 실행. 해당되는 주요 Spring 클래스는 org.springframework.transaction.jta.JtaTransactionManager, 이며 JTA 사양을 따르는 트랜잭션 코디네이터에 위임됩니다(대개 J2EE 서버이지만 반드시 그렇지는 않음).

PlatformTransactionManager 추상화의 중요한 가치는 애플리케이션이 특정한 트랜잭션 관리 환경에 얽매이지 않는다는 점입니다. 대신 다른 PlatformTransactionManager 구현 클래스를 선택함으로써 트랜잭션 전략을 쉽게 변경할 수 있습니다. 따라서 어떤 환경에서 애플리케이션 컴포넌트가 사용되건 애플리케이션 코드와 선언적 트랜잭션 경계 설정을 동일하게 유지할 수 있습니다.

예를 들어 단일 Oracle 데이터베이스를 사용하면서 애플리케이션의 기본 버전을 Tomcat에 배포할 수 있습니다. 거기서 편리한 Spring 트랜잭션 경계 설정을 활용하여 트랜잭션 전략으로 JDBC DataSourceTransactionManager를 선택할 수 있습니다. Spring은 트랜잭션의 경계 설정을 수행하고 JDBC 드라이버는 이에 상응하는 일반 JDBC 트랜잭션을 실행합니다.

두 개의 Oracle 데이터베이스를 사용하면서 동일한 애플리케이션의 다른 버전을 WebLogic Server에 배포할 수도 있습니다. 애플리케이션 코드와 트랜잭션 경계 설정은 변경할 필요가 없습니다. Spring이 트랜잭션의 경계 설정을 수행할 수 있도록 JtaTransactionManager를 트랜잭션 전략으로 선택하기만 하면 WebLogic Server의 트랜잭션 코디네이터가 알아서 트랜잭션을 실행합니다.

JTA UserTransaction 대 JTA TransactionManager

Spring의 JTA의 지원 내용을 좀 더 자세히 검토하겠습니다. 이 메커니즘을 이해하면 도움이 되지만 몰라도 걱정할 필요는 없습니다. 앞에서 살펴본 것 같이 간단하게 사용할 경우, J2EE 서버에서 제공하는 XA-aware DataSources와 함께 표준 JtaTransactionManager 정의만 있으면 됩니다.

기본 설정된 Spring의 JtaTransactionManager는 J2EE: java:comp/UserTransaction에 의해 지정된 표준 JNDI 위치로부터 JTA의 javax.transaction.UserTransaction 객체를 페치합니다. 이는 표준 J2EE 환경에서 사용되는 대부분의 경우 아무 문제도 없습니다.

그러나 기본 JtaTransactionManager는 트랜잭션 일시 중지를 수행하지 못합니다. 즉 PROPAGATION_REQUIRES_NEW와 PROPAGATION_NOT_SUPPORTED를 지원하지 않습니다. 그 이유는 표준 JTA UserTransaction 인터페이스가 새로운 트랜잭션의 시작과 완료만 지원하고, 트랜잭션의 일시 중지와 재시작을 지원하지 않기 때문입니다.

트랜잭션 일시 중지를 수행하려면 JTA에서 지정된 대로 표준 일시 중지와 재시작 메서드를 제공하는 javax.transaction.TransactionManager 인스턴스가 필요합니다. 불행히도, J2EE는 JTA TransactionManager에 대한 표준 JNDI 위치를 정의하지 않습니다! 따라서 벤더별 조회 메커니즘을 사용해야 합니다.

<bean id="transactionManager" 
   class="org.springframework.transaction.jta.JtaTransactionManager">
     <property name="transactionManagerName">
        <value>vendorSpecificJndiLocation</value>
     </property>
</bean>

J2EE는 본질적으로 JTA TransactionManager 인터페이스를 공용 API로 간주하지 않습니다. JTA 사양 자체는 컨테이너 통합 목적으로 TransactionManager 인터페이스를 선언합니다. 이는 이해가 가지만, JTA TransactionManager에 대한 표준 JNDI 위치는 특히 Spring과 같은 lightweight 컨테이너에 여전히 중요한 가치를 더합니다. J2EE 서버의 JTA TransactionManager에 대한 위치도 동일한 방식으로 처리됩니다.

JTA TransactionManager에 대한 액세스로 인해 Spring의 JtaTransactionManager는 물론 Hibernate, Apache OJB, Kodo JDO 같은 O/R 매핑 도구도 혜택을 받게 됩니다. 이들이 JTA 환경에서 캐시 동기화를 수행하려면(즉 JTA 트랜잭션 완료 시 캐시 잠금을 해제하려면) JTA TransactionManager에 액세스할 수 있어야 하기 때문입니다. 트랜잭션 동기화를 등록하는 기능은 JTA TransactionManager 인터페이스에서만 제공하고 UserTransaction에서는 제공하지 않습니다. 그 결과 이러한 도구는 각자의 벤더 전용 TransactionManager 조회 어댑터를 구현해야 합니다.

JTA TransactionManager에 대한 표준 JNDI 위치 정의는 많은 인프라스트럭처 소프트웨어 공급자들의 J2EE 요구 목록(wish list) 중 상위에 올라 있는 항목입니다. J2EE 5.0 사양 팀이 이 기능의 중요성을 인식하는 것이 중요합니다. 다행히도 WebLogic Server와 같은 고급 J2EE 서버는 벤더별 익스텐션을 비롯하여 JTA TransactionManager를 이미 공용 API로 간주합니다.

WebLogic JTA를 이용하여 Spring 트랜잭션 경계 설정

WebLogic Server의 경우 JTA TransactionManager의 공식적인 JNDI 위치는 javax.transaction.TransactionManager입니다. 이 값은 Spring의 JtaTransactionManager 에서 "transactionManagerName"으로 지정할 수 있습니다. 원칙적으로 이를 통해 WebLogic의 JTA 하위 시스템과 함께 Spring에서 트랜잭션 일시 중지를 수행할 수 있으며 PROPAGATION_REQUIRES_NEWPROPAGATION_NOT_SUPPORTED에 대한 지원이 활성화됩니다.

<bean id="transactionManager" 
   class="org.springframework.transaction.jta.JtaTransactionManager">
 <property name="transactionManagerName">
   <value>javax.transaction.TransactionManager</value>
 </property>
</bean>

표준 JtaTransactionManager와 여기에서 지원되는 일반 구성 옵션 외에도 Spring은 WebLogic의 JTA 익스텐션을 직접 이용하는 특별한 WebLogicJtaTransactionManager 어댑터를 제공합니다.

<bean id="transactionManager" 
    class="org.springframework.transaction.jta.WebLogicJtaTransactionManager"/>

WebLogic의 JTA TransactionManager는 편리한 자동 감지 기능 외에도 표준 JTA를 뛰어넘는 세 가지 중요한 기능을 제공합니다.

  • 트랜잭션 이름 - Spring의 트랜잭션 이름을 WebLogic Server에 노출하고 Spring 트랜잭션을 WebLogic의 트랜잭션 모니터에서 볼 수 있게 합니다. 기본적으로 Spring은 선언적 트랜잭션에 대해 완벽하게 검증된 메서드 이름을 사용합니다.
  • 트랜잭션별 격리 수준 - Spring의 트랜잭션 속성에서 지정된 격리 수준을 WebLogic JTA 트랜잭션에 적용합니다. 따라서 데이터베이스 격리 수준을 트랜잭션별로 지정할 수 있는데, 이는 표준 JTA에서 지원되지 않는 기능입니다.
  • 트랜잭션 재시작 수행 - 일시 중지된 트랜잭션이 rollback-only로 표시되어 있을 때에도 WebLogic 트랜잭션을 다시 시작합니다. 이렇게 하려면 기반이 되는 WebLogic의 확장된 TransactionManager 인터페이스를 사용하여 forceResume() 메서드를 호출해야 합니다.

다음 그림은 Spring에서 수행되는 몇몇 트랜잭션을 이름순으로 보여주는 WebLogic Server의 트랜잭션 모니터입니다.

Figure 2
그림 2. WebLogic Server의 트랜잭션 모니터 (클릭하면 큰 그림을 볼 수 있습니다.)

Spring의 WebLogicJtaTransactionManager는 WebLogic Server의 트랜잭션 매니저의 모든 기능을 Spring 기반의 애플리케이션에 효과적으로 노출합니다. 따라서 Spring트랜잭션 경계 설정은 EJB CMT에 필적할 만한 대안이 되며 동일한 수준의 트랜잭션 지원을 제공합니다.

트랜잭션을 일시 중지할 필요가 있거나 WebLogic의 JTA 확장자를 이용해야 할 경우에만 WebLogic에 맞게 JTA를 설정하면 됩니다. PROPAGATION_REQUIREDPROPAGATION_SUPPORTS와 같은 표준 트랜잭션 경계 설정에 대해서는 표준 JTA 설정을 사용할 수 있습니다.

Spring 과 EJB CMT

위에서 설명한 것과 같이 POJO에 대한 Spring의 선언적 트랜잭션 경계 설정은 기존의 EJB CMT의 대안으로 사용할 수 있습니다. 하지만 Spring과 EJB가 상호 배타적인 것은 아닙니다. Spring 애플리케이션 컨텍스트를 EJB facade 배후에서 백엔드로 사용하여, 데이터 액세스 객체(DAO)나 다른 정교한 비즈니스 객체를 관리할 수 있습니다.

EJB 시나리오에서 트랜잭션은 EJB CMT에 의해 수행됩니다. Spring의 데이터 액세스 지원 기능을 통해 자동으로 해당 환경이 감지되며 적절히 적응이 이루어집니다. 예를 들어 Spring에서 수행되는 트랜잭션과 마찬가지로 EJB에서 수행되는 트랜잭션에서도 Spring의 Hibernate 지원 기능을 통해 암시적 리소스 관리가 제공됩니다. 동일한 의미가 제공되므로 DAO 코드를 변경할 필요가 없습니다.

Spring은 실제 런타임 환경에서 DAO 구현을 효과적으로 분리합니다. DAO는 Spring 트랜잭션(백엔드로 실행되는 모든 트랜잭션 전략으로도)과 EJB CMT 트랜잭션에 모두 사용할 수 있습니다. 다른 환경에서 재사용할 수 있을 뿐 아니라 J2EE 컨테이너 외부에서 테스트용으로도 손쉽게 사용할 수 있습니다.

결론

Spring Framework는 J2EE와 비J2EE 환경에서 완전한 트랜잭션 경계 설정 기능을 제공합니다. 따라서 EJB가 없어도 유연하고 안전한 방법으로 편리하게 트랜잭션 경계 설정을 수행할 수 있습니다. EJB와는 달리 트랜잭션 POJO 애플리케이션 객체는 J2EE 컨테이너 외부에서도 쉽게 테스트하고 재사용할 수 있습니다.

Spring은 J2EE서버의 트랜잭션 코디네이터에 위임하는 JtaTransactionManager와 단일 JDBC DataSource(단일 대상 데이터베이스)에 대해 트랜잭션을 실행하는 JDBC DataSourceTransactionManager처럼 즉시 이용할 수 있는 다양한 트랜잭션 전략을 제공합니다. Spring은 백엔드 구성을 변경함으로써 다른 환경에 맞게 트랜잭션 전략을 쉽게 변경합니다.

표준 JTA 지원 외에도 Spring은 WebLogic Server의 JTA 익스텐션과의 정교한 통합 기능을 제공함으로써 트랜잭션 모니터링과 트랜잭션별 격리 수준 같은 고급 기능을 지원합니다. WebLogic Server에 대한 이런 특별한 지원을 바탕으로 Spring 기반의 애플리케이션에서 WebLogic 트랜잭션 매니저의 모든 기능을 사용할 수 있습니다.

Spring 트랜잭션 경계 설정은 특히 POJO 기반의 lightweight 아키텍처와 함께 사용할 경우 EJB CMT에 필적할 만한 대안이 됩니다. 단순히 선언적 트랜잭션 때문에 Local Sateless Session Bean을 선택해야 하는 경우, Spring 기반의 POJO 서비스 모델을 선택하면 훨씬 더 수준 높은 유연성, 테스트 편리성 및 재사용성이 제공됩니다.

리소스

Juergen Hoeller