이야기박스
Chapter 6. AOP(3) 포인트 컷과 트랜잭션 본문
포인트컷이란?
특정 조건에서 어드바이스(공통 기능의 코드)를 실행하기 위한 알고리즘입니다.
즉, 횡단 공통기능을 수행하기 위한 필터라고 생각하면 쉬울 것 같습니다.
1. 스프링 트랜잭션 어노테이션
포인트 컷 표현식 + 트랜잭션 속성을 이용하여 트랜잭션을 일괄적으로 적용하는건 일반적인 상황에서는 쓰일 수 있지만, 깊게 커스터마이징이 필요한 상황에서는 적합하지 않을 수 있습니다.
@Transactional
// the service class that we want to make transactional @Transactional public class DefaultFooService implements FooService { Foo getFoo(String fooName); Foo getFoo(String fooName, String barName); void insertFoo(Foo foo); void updateFoo(Foo foo); }
이런식으로 ...
이때 TransactionAttributeSourcePointcut이라는 포인트컷과 같이 사용되는데, 이때 포인트컷은 @Transactional 어노테이션이 있다면 타깃이 무엇이든간에 포인트컷의 결과로 선정됩니다. 즉, 이 어노테이션을 쓰면 포인트컷에 자동 등록된다고 생각하면 됩니다.
이 어노테이션을 사용하기 위해서는 어플리케이션 컨텍스트에 다음 정보를 추가하면 됩니다.
<tx:annotation-driven />
트랜잭션 속성과 포인트 컷
(@Transcational 어노테이션 사용했을 경우의 Advisor 동작 방식)
TransactionInterceptor는 메소드 이름 패턴으로 부여되는 속성 정보 대신, @Transcational 어노테이션의 트랜잭션 속성을 가져옵니다. ( AnnotationTransactionAttributeSource )
그리고 동시에 포인트 컷도 @Transactional 어노테이션을 참조하게 됩니다.(?) -- 포인트 컷의 선정 대상이기도 하기 때문
이 방식을 통하여서 포인트컷과 트랜잭션 속성을 하나의 어노테이션으로 정할 수 있게 됩니다. 특히 메소드 단위까지 지정이 가능하기 때문에 커스터마이징에 아주 특화되어 있습니다.
단, 너무 남발하게 되면 코드가 지저분해지고 가독성이 저하될 수 있기 때문에 신중히 사용해야 합니다.
대체 정책
'소제목이 @Transcational 대신 어떻게 쓰는가?' 같지만 실제로는 @Transactional 어노테이션의 동작 순서를 나타낸 것입니다.
1. 타겟 메소드에 적용되어 있는가?
2. 타겟 클래스에 적용되어 있는가?
3. 선언 메소드에 적용되어 있는가?
4. 선언 타입에 적용되어 있는가?
위 과정을 거쳐서 트랜잭션 적용 대상을 판단합니다. 이 순서를 개발할 때 참조하시면 되겠습니다.
실제 사용
<tx:attributes>
<tx:method name="get*" read-only="true"/>
<tx:method name="*"/>
</tx:attributes>
이런식으로 우선순위를 정하여 사용할 수 있습니다.
위 예제 같은 경우는 get*으로 시작하는 메소드는 읽기 전용 트랜잭션 속성을 지정해주어야 합니다.
2. 트랜잭션 지원 & 테스트
트랜잭션 지정 방법
- 선언적 트랜잭션 (Declarative transaction) : AOP를 이용해 코드 외부에서 트랜잭션의 기능을 부여해주고 속성을 지정
- 프로그램에 의한 트랜잭션 (Programmatic transcation) : 트랜잭션 API를 이용하여 직접 코드 안에 넣는 방법
트랜잭션의 자유로운 전파와 그로 인한 유연한 개발이 가능할 수 있었던 기술적 배경으로 AOP가 크게 작용하였습니다.
AOP로 인하여 프록시를 이용한 트랜잭션 부가기능을 애플리케이션 전반에 구현이 가능해졌습니다. 여기에 트랜잭션 추상화의 등장으로 선언적 트랜잭션 & 트랜잭션 전파가 손쉽게 이루어지게 되었습니다.
트랜잭션 매니저 & 동기화
* 트랜잭션을 통합하는 방법
1. 메소드를 생성하여 그 안에 원하는 동작을 지정
2. 원하는 동작의 메소드들을 호출하기 전에 트랜잭션을 지정하는 방법
테스트와 @Rollback
@Test
@Transactional // 테스트 클래스나 테스트 메소드에서 사용하면 기본적으로 롤백시킨다.
@Rollback(false) // false로 지정하면 롤백시키지 않는다.
public void transactionTest() {
...
}
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = "/applicationContext.xml")
@Transactional
@TransactionConfiguration(defaultRollback=false) // 사용하는 디폴트 트랜잭션 매니저 아이디는 "transactionManager" 이다.
public class UserServiceTest {
...
@Test
@Rollback // 여기서 @Rollback 을 사용하여 이 테스트 메소드만 롤백시킬 수 있다.
public void notRollbackTest() {
...
}
@Test
@Transactional(propagation=Propagation.NEVER) // 이 테스트에 한해서 트랜잭션을 시작되지 않도록 할 수 있다.
public void notUseTransactionTest() {
...
}
기타
3. AOP 전체 요약
- 트랜잭션 전파와 어노테이션 사용
'Programming Language > Spring' 카테고리의 다른 글
Chapter 8. 스프링이란 무엇인가? (0) | 2019.03.22 |
---|---|
Chapter 7. 스프링 핵심 기술의 응용 (0) | 2019.03.21 |
Chapter 6. AOP(2) (0) | 2019.02.08 |
Chapter 6. AOP(1) (0) | 2019.01.23 |
Chapter 5. 서비스 추상화 (0) | 2019.01.15 |