Transaction Template
2020. 5. 7. 18:37ㆍJava/Spring
728x90
1. @Transactional의 한계
public class TransactionInvoker {
private A1Dao a1dao;
private A2Dao a2dao;
public void setA1dao(A1Dao dao){
this.a1dao = dao;
}
public void setA2dao(A2Dao dao){
this.a2dao = dao;
}
// 외부에서 호출하는 method
public void invoke() throws Exception{
doInternalTransaction();
}
@Transactional
public void doInternalTransaction() throws Exception{
a1dao.insertA1();
a2dao.insertA2();
}
}
위의 코드를 실행해보면 @Transactional을 통해 Transaction이 적용되지 않는 것을 확인할 수 있습니다. Transaction이 적용되지 않는 이유는 @Transactional은 Proxy 방식으로 동작하는데, Proxy는 클래스 외부에서 호출하는 경우에만 동작하기 때문입니다.
그러면 invoke 메소드에 @Transactional을 설정할 수 있습니다. Spring Transaction은 method 시작 시점에 Connection 객체를 얻고 종료 시점에 반납합니다. 처리 시간이 긴 method의 경우에는 불필요하게 오랫동안 DB Connection을 점유하면서 DB Lock이 유지되는 시간이 길어지기 때문에 invoke 메소드에 설정해주지 않는 것이 좋습니다.
2. Transaction Template
Transaction Template이란 개발자가 Transaction의 시작 및 종료 시점을 명시적으로 결정할 수 있도록 Spring에서 제공하는 방법입니다. 아래의 예제처럼 Transaction Template은 Spring으로부터 TransactionManager를 주입받고 Transaction 속성을 설정해 줍니다. 그리고 execute 메소드 내에서 로직을 실행합니다.
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.support.TransactionTemplate;
import org.springframework.transaction.TransactionDefinition;
import org.springframework.transaction.support.TransactionCallbackWithoutResult;
import org.springframework.transaction.TransactionStatus;
public class TransactionInvoker {
private A1Dao a1dao;
private A2Dao a2dao;
private TransactionTemplate transactionTemplate;
public void setA1dao(A1Dao dao){
this.a1dao = dao;
}
public void setA2dao(A2Dao dao){
this.a2dao = dao;
}
public void setTransactionManager(PlatformTransactionManager transactionManager){
this.transactionTemplate = new TransactionTemplate(transactionManager);
this.transactionTemplate.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED);
}
public void invoke() throws Exception{
doInternalTransaction();
}
private void doInternalTransaction() throws Exception{
transactionTemplate.execute(new TransactionCallbackWithoutResult(){
public void doInTransactionWithoutResult(TransactionStatus status){
try{
a1dao.insertA1();
a2dao.insertA2();
}
catch(Exception e){
status.setRollbackOnly();
}
return;
}
});
}
}
728x90
'Java > Spring' 카테고리의 다른 글
Spring Batch (0) | 2020.07.02 |
---|---|
Spring Boot (0) | 2020.06.09 |
Spring Singleton (0) | 2020.05.01 |
@ExceptionHandler (0) | 2020.04.26 |
AOP (0) | 2020.04.18 |