티스토리 뷰

0. 배경

:: Spring Transaction 은 트랜잭션 추상화(PlatformTransactionManager)로 트랜잭션의 시작과 끝을 알려줌

:: TransactionDefinition 은 트랜잭션 세부 옵션

public interface PlatformTransactionManager extends TransactionManager {
		TransactionStatus getTransaction(@Nullable TransactionDefinition definition) throws TransactionException;
        // ...
}
  • Spring Transaction = 트랜잭션 동기화 + 트랜잭션 추상화
    1. 트랜잭션 동기화 :: TransactionSynchronizationManager 내 Connection 보관
    2. 트랜잭션 추상화 :: PlatformTransactionManager 통해 트랜잭션 시작 및 종료

    + JdbcTemplate 통해 Connection 사용을 개발자가 관리 X


0.1 하지만!

:: 직접 PlatformTransactionManager 사용 시, 매번 PlatformTransactionManager 보일러플레이트를 작성해야 한다.

==> 이를 해결하기 위해 프로그래밍형 or 선언형으로 트랜잭션을 사용함

     
LV 1) Low-level API PlatformTransactionManager  
LV 2) High-level API - 프로그래밍형(Programmatic) 트랜잭션
:: TransactionTemplate
- 선언적(Declarative) 트랜잭션
::@Transactional(Spring AOP 사용)

1. 프로그래밍형(Programmatic) 트랜잭션 : TransactionTemplate

:: JTA UserTransaction API 사용하는것과 유사

:: TransactionTemplate이 PlatformTransactionManager의 보일러플레이트를 내장하여 대신 적용


@Service
@RequiredArgsConstructor
public class SimpleService {
	  private final TransactionTemplate transactionTemplate;
	
	  public void method() {
		    String result = transactionTemplate.execute(new TransactionCallback<String>() {
			      public String doInTransaction(TransactionStatus status) {
				        jdbcTemplate.update(...);
				        jdbcTemplate.update(...);
				        return "";
			      }
		    });
	  }
}

 

위와 같은 형태를 템플릿 콜백 패턴이라 함

더보기

- 템플릿 콜백 패턴(Template Callback Pattern)

:: 전략 패턴 + 익명 구현 객체
1) 템플릿 메서드 패턴 :: Abstract Class :: 일부
2) 전략 패턴 :: Interface + Concrete Class :: 전체
3) 템플릿 콜백 패턴 :: Interface + Anonymous Class :: 익명

:: 기본적인 템플릿(구조화된 흐름) + 사용자의 로직을 삽입할 수 있도록 콜백 메서드를 호출하는 방식

:: 처리 과정에서 반복적인 부분과 사용자 정의 가능한 부분을 분리 -> 코드 재사용성 + 코드의 유연성 제공


public void method() {
	String result = transactionTemplate.execute((status) -> {
    	jdbcTemplate.update(...);
        jdbcTemplate.update(...);
	return "";
    });
}

- TransactionCallback가 인터페이스이기 때문에, 람다 표현식 형태로 파라미터에 삽입 가능


1.1 TransactionTemplate 옵션

== PlatformTransactionManager 옵션

 

// setter를 통해 적용

PlatformTransactionManager transactionManager = new DataSourceTransactionManager(dataSource);
TransactionTemplate transactionTemplate = new TransactionTemplate(transactionManager);
transactionTemplate.setIsolationLevel(TransactionDefinition.ISOLATION_REPEATABLE_READ);
transactionTemplate.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED);
transactionTemplate.setTimeout(-1);
transactionTemplate.setReadOnly(false);

2. 선언적(Declarative) 트랜잭션 : @Transactional (Spring AOP)

:: @Transactional 어노테이션 통해 PlatformTransactionManager 보일러플레이트가 내장하여 대신 적용

@Service
public class SimpleService {

	@Transactional
	public void method() {
    		jdbcTemplate.update(...);
        	jdbcTemplate.update(...);
	}
}

 

2.1 @Transactional 옵션

== PlatformTransactionManager 옵션

// @Transactional 어노테이션 내 설정값으로 적용

@Transactional(
	propagation   = Propagation.REQUIRED,      // Propagation 전파
	isolation     = Isolation.REPEATABLE_READ, // Isolation Level 격리성 레벨
	timeout       = -1,                        // Timeout 트랜잭션 타임아웃
	readOnly      = false,                     // ReadOnly R 만 허용, CUD 방지
	rollbackFor   = Exception.class,
	noRollbackFor = RuntimeException.class
)

public void method() {
	  jdbcTemplate.update(...);
	  jdbcTemplate.update(...);
}

3. 프로그래밍적 트랜잭션 관리(TransactionTemplate가 필요한 경우)

  • 보통 선언적 트랜잭션 방식인 @Transactional을 많이 사용
    But, 선언적 트랜잭션은 메서드나 클래스 레벨에 Spring AOP 란 프록시 자동생성 기법으로 적용되기때문에
    1. 메서드 내 일부분에만 트랜잭션 적용 X
    2. 프록시 기반으로 동작되기에, Self Invocation시 트랜잭션을 적용 X

위와 같은 문제가 발생할 경우, 프로그래밍형 트랜잭션 방식인 TransactionTemplate를 사용한다.

 

  • 메서드 내 일부분에만 트랜잭션 적용할 수 없기 때문에
    • @Transactional 적용하려는 메서드 로직이 너무 긴 경우
      → 불필요하게 너무 빨리 트랜잭션(Connection)이 시작/선점되어 버리는 문제
      ⇒ LazyConnectionDataSourceProxy로 트랜잭션(Connection)을 원하는 시점에 시작/선점 가능(해결 가능)

    • But, TransactionTemplate으로 아래의 문제도 한번에 처리 가능

  • 프록시 기반으로 동작되기에 Self Invocation 시 트랜잭션을 적용할 수 없기 때문에
    • @Transactional 적용하려는 메서드 내 트랜잭션과 무관한데 오래 걸리는 로직이 중간에 걸려있는 경우
      → 해당 트랜잭션에 물려있는 모든 쿼리들이 실제로 DB 에 적용되기까지 오래걸려 타 작업을 막아버린다

    • ⇒ TransactionTemplate 통해 트랜잭션과 무관한 로직들만 제외하고 부분적으로만 트랜잭션을 건다.

참고

ASAC 수업자료

 

 

[Spring] 트랜잭션 관리를 위한 TransactionTemplate의 활용

1. 트랜잭션 관리를 위한 TransactionTemplate의 활용[ 트랜잭션 관리를 위한 TransactionTemplate의 활용 ]스프링으로 개발을 하다 보면 선언적 트랜잭션을 자주 사용하게 된다. 선언적 트랜잭션(Declarativ

mangkyu.tistory.com

 

공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2025/05   »
1 2 3
4 5 6 7 8 9 10
11 12 13 14 15 16 17
18 19 20 21 22 23 24
25 26 27 28 29 30 31
글 보관함