[egov] 트랜잭션 관리
1. 트랜잭션 관리 설정
<!-- context-transaction.xml -->
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.0.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.0.xsd">
<!-- 트랜잭션 관리자를 설정한다. -->
<bean id="txManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"/>
</bean>
<!-- 트랜잭션 Advice를 설정한다. -->
<tx:advice id="txAdvice" transaction-manager="txManager">
<tx:attributes>
<tx:method name="*" rollback-for="Exception"/>
</tx:attributes>
</tx:advice>
<!-- 트랜잭션 Pointcut를 설정한다.--->
<aop:config>
<aop:pointcut id="requiredTx" expression="execution(* egovframework.rte.sample..impl.*Impl.*(..))"/>
<aop:advisor advice-ref="txAdvice" pointcut-ref="requiredTx" />
</aop:config>
</beans>
이 설정 파일은 Spring 프레임워크에서 트랜잭션 관리를 설정하는 데 사용되는 XML 파일입니다. 여기에서 중요한 요소는 트랜잭션 관리(트랜잭션 롤백, 커밋 등)를 자동으로 처리하기 위한 Advice와 포인트컷(Pointcut)입니다. 각 용어의 의미를 설명하면 다음과 같습니다.
(1) Advice (조언)
- advice는 AOP(Aspect-Oriented Programming, 관점 지향 프로그래밍)에서 사용되는 개념으로, 실제 로직에 개입하여 특정한 동작을 추가하는 기능입니다. 여기서는 트랜잭션 관리와 관련된 Advice입니다. 트랜잭션을 시작하고, 메서드 실행 후 성공하면 커밋하거나, 예외가 발생하면 롤백하는 동작을 정의합니다.
- <tx:advice>는 트랜잭션과 관련된 처리를 담당하며, txManager라는 트랜잭션 매니저를 사용해 트랜잭션을 관리하도록 설정됩니다.
- <tx:method name="*" rollback-for="Exception"/>은 모든 메서드 실행 시, 예외가 발생하면 트랜잭션을 롤백하도록 설정하는 부분입니다.
(2) 포인트컷(Pointcut)
- pointcut은 AOP의 핵심 개념으로, Advice가 적용될 메서드나 클래스를 정의하는 역할을 합니다. 즉, 어느 지점에서 트랜잭션 관리가 필요한지를 지정하는 규칙입니다.
- <aop:pointcut>에서 id="requiredTx"로 정의된 포인트컷은 트랜잭션 관리가 필요한 메서드를 지정합니다.
- expression="execution(* egovframework.rte.sample..impl.*Impl.*(..))"는 특정 패턴을 따르는 메서드에 트랜잭션을 적용합니다. 예를 들어, egovframework.rte.sample 패키지 아래 impl 패키지에 있는 클래스 중, 이름이 Impl로 끝나는 클래스의 모든 메서드에 대해 트랜잭션 관리가 적용된다는 의미입니다.
(3) 트랜잭션 관리 흐름
- txAdvice로 정의된 트랜잭션 Advice는 txManager 트랜잭션 관리자를 사용하여 트랜잭션을 처리합니다.
- 포인트컷 requiredTx는 트랜잭션 관리가 필요한 메서드를 지정하고, Advice는 이 메서드에 대해 트랜잭션을 처리하게 됩니다.
- advisor는 txAdvice(트랜잭션 관리 동작)와 requiredTx(적용할 메서드 집합)를 연결해줍니다.
이 설정은 트랜잭션 관리가 필요한 메서드에 대해 자동으로 트랜잭션을 시작하고, 성공적으로 실행되면 커밋하고, 예외가 발생하면 롤백하는 동작을 수행하도록 합니다.
2. expression 속성
context-transaction.xml에서 AOP 설정을 위해 aop:config 태그를 사용하는 경우, expression 속성은 트랜잭션이 적용될 메서드를 정의하는 데 사용됩니다. AOP는 특정 메서드 호출에 대해 관심사(트랜잭션, 로깅 등)를 분리하여 처리하는 것을 목표로 하며, 이때 expression을 사용하여 트랜잭션 처리를 할 메서드를 식별할 수 있습니다.
(1) aop:config와 expression의 구조
- aop:config 태그: aop:config 태그는 AOP 설정을 정의하는 루트 태그로, 그 안에 aop:pointcut과 aop:advisor 같은 요소들을 포함할 수 있습니다.
- aop:pointcut: 포인트컷(pointcut)은 AOP에서 어떤 메서드가 트랜잭션 관리의 대상이 될지를 정의합니다. expression 속성에서 포인트컷을 설정할 수 있습니다.
- expression의 주요 구성 요소:
- execution(): 메서드 실행을 기준으로 하는 포인트컷 표현식입니다.
- 접근 제어자(public, private 등): 메서드의 접근 제어자를 정의합니다.
- 리턴 타입(*): 메서드의 반환 타입을 정의합니다.
- 패키지 및 클래스: 특정 패키지 및 클래스에 있는 메서드를 대상으로 설정할 수 있습니다.
- 메서드명: 특정 메서드명을 지정하거나 패턴을 사용하여 여러 메서드를 지정할 수 있습니다.
- 파라미터: 메서드에 전달되는 파라미터의 타입을 지정할 수 있습니다.
<aop:config>
<!-- 트랜잭션이 적용될 메서드를 지정하는 포인트컷 -->
<aop:pointcut id="transactionPointcut" expression="execution(* com.example.service..*ServiceImpl.*(..))" />
<!-- 트랜잭션 어드바이스 적용 -->
<aop:advisor advice-ref="transactionAdvice" pointcut-ref="transactionPointcut" />
</aop:config>
위 예제에서 expression의 의미는 다음과 같습니다:
- execution(..): 메서드 호출을 대상으로 합니다.
- *: 모든 반환 타입을 허용합니다.
- com.example.service..*ServiceImpl.*(..): com.example.service 패키지 내의 모든 서브 패키지(..)에 있는 클래스 중에서 이름이 ServiceImpl로 끝나는 클래스의 모든 메서드에 대해 트랜잭션 처리를 적용합니다.
- (..): 메서드 파라미터의 타입에 상관없이 모든 메서드를 대상으로 합니다.
(2) expression의 구체적 예시
특정 클래스의 모든 메서드에 트랜잭션 적용
<aop:pointcut id="allMethodsInClass" expression="execution(* com.example.MyClass.*(..))" />
com.example.MyClass 클래스의 모든 메서드에 트랜잭션을 적용합니다.
특정 이름의 메서드에만 트랜잭션 적용
<aop:pointcut id="specificMethod" expression="execution(* com.example.MyClass.save*(..))" />
com.example.MyClass 클래스에서 save로 시작하는 메서드들에만 트랜잭션을 적용합니다.
패키지 전체에 트랜잭션 적용
<aop:pointcut id="packagePointcut" expression="execution(* com.example.service..*.*(..))" />
com.example.service 패키지 및 그 하위 패키지에 있는 모든 클래스의 모든 메서드에 트랜잭션을 적용합니다.
특정 패키지에 트랜잭션 적용
<aop:pointcut id="packagePointcut" expression="execution(* com.example.menu.collect..impl.*Impl.*(..))" />
- com.example.menu.collect..impl.*Impl:
- com.example.menu.collect 패키지와 그 하위 패키지(..)에 있는 모든 클래스 중에서,
- Impl로 끝나는 이름을 가진 클래스들이 대상입니다. 예를 들어 MenuServiceImpl, ItemCollectImpl 등 Impl로 끝나는 클래스가 모두 포함됩니다.
- impl 폴더 아래에 위치한 클래스들에만 적용됩니다.
- *: 해당 클래스 내의 모든 메서드가 대상입니다. 메서드 이름이 무엇이든 상관없습니다.
- (..): 메서드의 파라미터는 무엇이든 상관없다는 의미입니다. 즉, 파라미터 타입이나 개수에 관계없이 모든 메서드를 대상으로 합니다.
- com.example.menu.collect.impl.MenuServiceImpl
- com.example.menu.collect.subpackage.impl.ItemCollectImpl
위 클래스들 내의 모든 메서드가 이 표현식의 대상이 됩니다.
출처 : https://www.egovframe.go.kr/wiki/doku.php?id=egovframework:rte:fdl:aop:egovrteaopguide