티스토리 뷰
0. 배경
:: Spring Transaction 은 트랜잭션 추상화(PlatformTransactionManager)로 트랜잭션의 시작과 끝을 알려줌
:: TransactionDefinition 은 트랜잭션 세부 옵션
public interface PlatformTransactionManager extends TransactionManager {
TransactionStatus getTransaction(@Nullable TransactionDefinition definition) throws TransactionException;
// ...
}
- Spring Transaction = 트랜잭션 동기화 + 트랜잭션 추상화
- 트랜잭션 동기화 :: TransactionSynchronizationManager 내 Connection 보관
- 트랜잭션 추상화 :: 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 란 프록시 자동생성 기법으로 적용되기때문에- 메서드 내 일부분에만 트랜잭션 적용 X
- 프록시 기반으로 동작되기에, Self Invocation시 트랜잭션을 적용 X
위와 같은 문제가 발생할 경우, 프로그래밍형 트랜잭션 방식인 TransactionTemplate를 사용한다.
- 메서드 내 일부분에만 트랜잭션 적용할 수 없기 때문에
- @Transactional 적용하려는 메서드 로직이 너무 긴 경우
→ 불필요하게 너무 빨리 트랜잭션(Connection)이 시작/선점되어 버리는 문제
⇒ LazyConnectionDataSourceProxy로 트랜잭션(Connection)을 원하는 시점에 시작/선점 가능(해결 가능) - But, TransactionTemplate으로 아래의 문제도 한번에 처리 가능
- @Transactional 적용하려는 메서드 로직이 너무 긴 경우
- 프록시 기반으로 동작되기에 Self Invocation 시 트랜잭션을 적용할 수 없기 때문에
- @Transactional 적용하려는 메서드 내 트랜잭션과 무관한데 오래 걸리는 로직이 중간에 걸려있는 경우
→ 해당 트랜잭션에 물려있는 모든 쿼리들이 실제로 DB 에 적용되기까지 오래걸려 타 작업을 막아버린다 - ⇒ TransactionTemplate 통해 트랜잭션과 무관한 로직들만 제외하고 부분적으로만 트랜잭션을 건다.
- @Transactional 적용하려는 메서드 내 트랜잭션과 무관한데 오래 걸리는 로직이 중간에 걸려있는 경우
참고
ASAC 수업자료
[Spring] 트랜잭션 관리를 위한 TransactionTemplate의 활용
1. 트랜잭션 관리를 위한 TransactionTemplate의 활용[ 트랜잭션 관리를 위한 TransactionTemplate의 활용 ]스프링으로 개발을 하다 보면 선언적 트랜잭션을 자주 사용하게 된다. 선언적 트랜잭션(Declarativ
mangkyu.tistory.com
'정리용 > DB' 카테고리의 다른 글
[DB 기초] 8. Spring AOP - Transaction (0) | 2025.04.01 |
---|---|
[DB 기초] 7-2. 선언형 트랜잭션의 주의점 (0) | 2025.03.25 |
[DB 기초] 7. 트랜잭션 - 동기화와 추상화 (0) | 2025.03.24 |
[DB 기초] 6-2. JDBC Template (0) | 2025.03.19 |
[DB 기초] 6-1. JDBC API / Driver (0) | 2025.03.19 |
- Total
- Today
- Yesterday
- useContext
- git
- useReducer
- ssh
- useRef
- useState
- useEffect
- react
- useLayoutEffect
- asac#asac7기
- asac7#asac
- ASAC
- memo
- acas#acas7기
- useMemo
- asac7기
- acac
- asac7
- useCallback
- Nginx
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |