티스토리 뷰

spring framework 를 이용하여 트랜잭션을 제어할 일이 생기면 대부분 @Transactional 애노테이션을 이용할 것이다. 이 방식은 가장 간단하기도하며 spring 을 공부하는 자료들에선 대부분 선언적으로 트랜잭션을 다루는 세련된 기법이라고 소개한다. spring 을 공부할때 접하게되는 대표적 키워드들중 AOP 가 있는데, AOP 를 가장 처음으로 접하게 되는 기술이기도하다.

 

다만 이 방식에는 몇가지 불편한점이 있는데

 

1. 메서드 레벨에 AOP 가 적용되기 때문에 트랜잭션 단위도 메서드 레벨로 적용(메서드 내에서 지정 불가능)

2. self invocation 에서 트랜잭션 적용 불가

 

가 대표적이다. 특히 2번은 spring 을 처음 접하는 주니어 개발자라면 이 문제로 인한 삽질을 한번쯤은 하고 넘어간 기억이 있을 것이다.

그리고 대부분은 이 문제를 해결하기위해 상위 메서드에 애노테이션을 달아주거나, 트랜잭션이 걸릴 수 있도록 클래스를 분리하는 식으로 문제를 해결했을 것이다.

 

이런 상황에서 사용할 수 있도록 spring 은 선언적 트랜잭션 외에도 트랜잭션 관리 API 를 제공하는데, 대표적인게 TransactionTemplate 클래스이다.

 

잘 몰라서 그렇지 사용하는 것 자체는 어려울게 없다.

@Component                                                                                 
class Sample {                                                                             
	private final TransactionTemplate transactionTemplate;                                 
                                                                                           
	public Sample(TransactionTemplate transactionTemplate) {                               
		this.transactionTemplate = transactionTemplate;                                    
	}                                                                                      
                                                                                           
	void execute() {                                                                       
		String result = transactionTemplate.execute(new TransactionCallback<String>() {    
			@Override                                                                      
			public String doInTransaction(TransactionStatus status) {                      
				return "";                                                                 
			}                                                                              
		});                                                                                
	}                                                                                      
}

spring 의 여타 ~Template 클래스들과 마찬가지로 템플릿 콜백 패턴을 사용하여 API 를 이용할 수 있다. TransactionCallback 은 functional interface 이므로 람다 표현식을 이용해도 좋다.

void execute() {                                               
	String result = transactionTemplate.execute(status -> ""); 
}

지금같은경우 트랜잭션 실행 결과를 String 으로 받고있지만 결과가 필요하지 않을땐 TransactionCallbackWithoutResult 이용할 수도 있다.

void execute() {                                                                 
	transactionTemplate.execute(new TransactionCallbackWithoutResult() {         
		@Override                                                                
		protected void doInTransactionWithoutResult(TransactionStatus status) {  
                                                                                 
		}                                                                        
	});                                                                          
}

참고로 TransactionCallbackWithoutResult 는 추상 클래스이기때문에 람다 표현식을 이용할 수 없다. 해당 API 가 람다 표현식이 없던 시절에 만들어진 상당히 오래된 API 라서(2003년) 지금은 이 추상 클래스를 이용할 일은 없지않을까 싶다.

댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2024/12   »
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
글 보관함