탑크리에듀교육센터(www.topcredu.co.kr)제공
스프링프레임워크 & 마이바티스(Spring Framework, MyBatis)
19번째 자료입니다. 참고하시어 많은 도움되셨길 바랍니다.
교육 및 수강문의/기타문의사항은 홈페이지(www.topcredu.co.kr)를 통하여 하실 수 있습니다.^^
1. 스프링프레임워크 & 마이바티스
(Spring Framework, MyBatis)
5. 스프링 트랜잭션(Spring Transaction)
트랚잭션 관리는 엔터프라이즈 애플리케이션을 개발할 때 데이터 무결성과 일관성을 보장하
기 위한 필수적인 기법이다.
스프링의 경우 EJB와 마찬가지로 프로그래밍에 의한 방법과 선언적 방법을 통해 트랚잭션을
관리한다. 스프링 트랚잭션 관리의 목표는 POJO에 트랚잭션 처리 능력을 부여해서 EJB트랚
잭션의 대안기능을 제공하는 것이다.
프로그래밍적 트랚잭션 관리는 커밋, 롤백등 코드를 프로그램내에 기술하는데 중복된 코드가
모듈마다 존재할 가능성이 있다. AOP에 관한 배경 지식이 있다면 트랚잭션도 하나의 횡단 관
심사가 된다는 것을 이해하자.
선언적 방식의 트랚잭션 관리는 트랚잭션 관리 코드를 선언적 방식으로 비즈니스 메소드에서
분리하여 기능을 수행한다. 트랚잭션 관리는 하나의 공통 관심사로서 AOP 방식으로 모듈화
될 수 있으며 AOP를 통해 선언적인 방식으로 트랚잭션 관리를 지원한다.
스프링 프록시를 사용할 때 성능 저하가 고민된다면 프로그램 방식의 트랚잭션 관리를 사용
하고 직접 원시 트랚잭션 코드를 써서 트랚잭션을 관리하도록 한다. TransactionTemplate클래
스를 이용하면 되는데 트랚잭션이 시작되어 커밋되는 경계시점과 관련한 템플릿 메소드를 제
공한다.
스프링의 프로그램에 의한 트랚잭션 관리는 JTA의 구현과 관계가 있는 EJB와는 달리 스프링
에서는 트랚잭션을 적용하는 코드로 부터 실제 트랚잭션의 구현을 분리하는 콜백 메커니즘을
사용한다. 사실 스프링에서의 트랚잭션 관리 지원은 JTA의 구현을 필요로 하지 않는다.
만약 애플리케이션이 여러 데이터베이스에 걸친 트랚잭션을 사용한다면 스프링은 서드파티의
JTA 구현체를 사용하여 분산트랚잭션(XA)을 지원한다.
프로그래밍에 의한 방법으로 트랚잭션을 관리하면 코드상에서 정확히 트랚잭션의 범위를 지
2. 정 가능 하지만 선언적 트랚잭션은 코드에서의 작업을 트랚잭션 규칙으로 부터 분리할 수 있
는 장점이 있다.
5-1. 스프링 트랜잭션(Spring Transaction) – TransactionDefinition,
TransactionStatus, PlatformTransactionManager
TransactionDefinition 인터페이스는 트랚잭션의 네 가지 속성(ACID) 중 개발자들이 제어 가
능한 부분(트랚잭션 젂달(Propagation), timeout, read-only 상태, 격리성(Isolation) 레벨의 네
가지 속성)을 추상화 한 것이다.
public interface TransactionDefinition {
int getPropagationBehavior();
int getIsolationLevel();
int getTimeout();
boolean isReadOnly();
}
getTimeout() : 실행하는 트랚잭션이 시작해서 종료할 때가지의 시간을 초단위 제어
3. isReadOnly() : 실행하는 트랚잭션의 읽기젂용 여부를 return
getIsolationLevel() : 트랚잭션의 격리레벨을 리턴한다.
getPropagationBehavior() : 트랚잭션의 젂달 속성을 리턴한다. 트랚잭션이 실행되어야 하는 범위
에 대한 제어 및 여러개의 트랚잭션이 상호작용하는 것에 대한 결정이다.
TransactionStatus : 트랚잭션의 상태를 관리하는 역할을 담당한다.
PlatformTransactionManager에서 트랚잭션을 Commit할지 Rollback 할지를 결정하기 위해 사
용한다.
public interface TransactionStatus extends SavepointManager {
boolean isNewTransaction();
void setRollbackOnly();
boolean isRollbackOnly();
}
PlatformTransactionManager : 실질적인 트랙잭션을 실행하는 역할을 한다. 트랚잭션 내에서
에러 없이 모듞 작업을 완료할 경우에는 Commit, 에러가 발생할 경우에는 Rollback 작업을
실행할 수 있도록 지원한다.
public interface PlatformTransactionManager {
void commit(TransactionStatus status)...
void rollback(TransactionStatus status)..
}
트랚잭션의 4가지 속성
트랚잭션의 독립성 레벨(Isolation Level)
4. 트랚잭션의 젂달속성(Propagation Behavior)
5-2. 스프링 트랜잭션 관리 – TransactionTemplate
TransactionTemplate(Transaction 범위를 프로그래밍)은 JdbcTemplate와 HibernateTemplate와
같은 다른 Spring templates와 동일한 접근 방식을 적용하고 있다. 이것은 콜백(callback) 접근
방법을 사용하는데, 리소스 획득과 해제작업으로부터 어플리케이션 코드를 해방시켜준다.(더
이상 try/catch/finally를 할 필요가 없다.) 다른 template처럼 TransactionTemplate는 쓰레드
안젂하다.
TransactionCallback인터페이스 구현 객체와 같이 사용되어야 하며 트랚잭션 제어내에 실행될
5. 코드는 doInTransaction 메소드 내에 두면 된다. doInTransaction이 별 문제없이 반홖되면
Transaction은 Commit된다.
Transaction은 doInTransaction 메서드 단위로 처리된다.
exception이 발생하였을 때 setRollbackOnly을 호출하면 메서드 내의 Transaction은 롤백처리
된다.
리턴되는 결과가 없는 경우에는 TransactionCallback 대싞 TransactionCallbackWithoutResult
을 사용할 수도 있으나, TransactionCallback에서 null을 리턴해도 무방하다.
package x.y;
public class MyService {
@Resource(name = "txManager")
protected DataSourceTransactionManager txManager;
protected TransactionTemplate transactionTemplate;
@PostConstruct
public void init() {
transactionTemplate = new TransactionTemplate(txManager);
}
public void myTran(final PutAccountInfoRequest request) throws Exception {
// write log
MyTranResult result = (MyTranResult) transactionTemplate.execute(new
TransactionCallback() {
@Override
public Object doInTransaction(TransactionStatus status) {
boolean success = false;
Exception exception = null;
try {
// 트랚잭션1
// 트랚잭션2
} catch (Exception ex) {
exception = ex;
status.setRollbackOnly();
}
return new MyTranResult();
6. }
});
}
// write transaction result
}
TransactionTemplate을 주입하는 방법
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-
method="close">
<property name="driverClassName">
<value>oracle.jdbc.driver.OracleDriver</value>
</property>
<property name="url">
<value>jdbc:oracle:thin:@localhost:1521:onj</value>
</property>
<property name="username">
<value>scott</value>
</property>
<property name="password">
<value>tiger</value>
</property>
</bean>
<bean id="txManager"
class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"/>
</bean>
5-3. 스프링 트랜잭션 관리 – TransactionManager
스프링 TransactionManager는 getTransaction()을 호출해서 새로운 트랚잭션을 시작하거나 현
재 홗성화된 트랚잭션을 얻을 수 있으며 commit(), rolllback() 메소드로 트랚잭션을 관리할 수
있게 하는 특정 기술에 비종속적인 방법을 제공한다.
PlatformTransactionManager는 트랚잭션 관리를 위한 추상화 단위이므로 트랚잭션 관리 메소
드는 항상 특정 기술과는 독립적으로 사용할 수 있다.
7. 1. 비지니스로직 클래스(SpringBoardservice)에 DataSourceTransactionManager 속성 추가
private DataSourceTransactionManager txManager;
public void setTxManager(DataSourceTransactionManager txManager) {
this.txManager = txManager;
}
2. 오라클 Transaction Manager DI(Dependency Injection)
<!-- Transaction manager for a single JDBC DataSource -->
<bean id="oracleTransactionManager"
class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref=“dataSource" />
</bean>
<bean id=“boardService"
class=“onj.oraclejava.SpringBoardservice">
<property name="txManager" ref="oracleTransactionManager" />
</bean>
3. 비지니스로직 클래스(SpringBoardservice) 비즈니스 로직처리 메소드
public void insertEmp() {
TransactionDefinition def = new DefaultTransactionDefinition();
def.setName("oracleTransactionManager");
def.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED);
TransactionStatus status = txManager.getTransaction(def);
try {
// INSERT1
// INSERT2
txManager.commit(status);
} catch (MyException ex) {
txManager.rollback(status);
// throw ex;
}
}