프로젝트를 진행하다 Transaction을 수행해야 하는 query가 있었습니다. 그때 저는 iBatis의 Transaction을 통해 다음과 같이 구현하였습니다.
(Spring에서 제공하는 SqlMapClientTemplate를 이용하여 iBatis를 사용했습니다)
SqlMapClient sqlClient = template.getSqlMapClient();
try {
sqlClient.startTransaction();
template.insert("turotial.dataInsert", data);
template.insert("tutorial.updateInfo", data);
sqlClient.commitTransaction();
return true;
} catch (SQLException e) {
e.printStackTrace();
return false;
} finally {
sqlClient.endTransaction();
}위와 같이 insert하고 update부분을 iBatis의 transaction으로 묶으려고 하였습니다.
하지만 우연치 않게 iBatis의 Transaction이 먹히지 않는것을 발견하였습니다. 왜이럴까 고민하다가 Spring에서 제공하는 Transaction을 통해 구현해 보기로 하였고, 결국 Transaction이 제대로 동작하는것을 확인 할 수 있었습니다.
저같은 경우는 Spring project를 할때 db연동에 관련한 모든 bean들을 applicationContext-iBatis.xml에 몰아 둡니다.( 관리하기가 더 편하더라구요.. 개인적 생각입니다.^^)
저는 이 ibatis.xml 에 ibatis를 통해 DB에 접근할 dataSource bean을 설정해 두었습니다.
1. transactionManager와 transactionTemplate을 bean으로 등록합니다.
<bean id="dataSource" class="org.springframework.jndi.JndiObjectFactoryBean">
<property name="jndiName" value="java:comp/env/jdbc/tutorial"/>
</bean>
<bean id="sqlMapClient" class="org.springframework.orm.ibatis.SqlMapClientFactoryBean">
<property name="configLocation" "classpath:sqlMapConfig.xml" />
<property name="dataSource" ref="dataSource" />
</bean>
<bean id="template"
class="org.springframework.orm.ibatis.SqlMapClientTemplate"
p:sqlMapClient-ref="sqlMapClient"/>
<bean id="transactionManager" "org.springframework.jdbc.datasource.DataSourceTransactionManager"
p:dataSource-ref="dataSource"/>
<bean id="transactionTemplate"
class="org.springframework.transaction.support.TransactionTemplate"
p:transactionManager-ref="transactionManager"/>위와 같이 transactionManager와 transactionTemplate bean을 dataSource를 통해 생성합니다.
2. transactionTemplate를 사용할 bean에 property로 설정합니다.
<bean id="tutorialDAO" class="tutorial.TutorialDAOImpl"> <property name="template" ref="template"/> <property name="transactionTemplate" ref="transactionTemplate"/> </bean>
3. 해당 DAOImpl 클래스에서 field로 transactionTemplate와 setter method를 구현하여 DI가 되도록 작업해 줍니다.
4. 다음과 같이 transactionTemplate를 통해 transaction을 구현합니다.
public boolean transactionTest(final TutirialVO vo ) throws SQLException{
boolean result = false;
result = (Boolean)transactionTemplate.execute( new TransactionCallback() {
public Object doInTransaction(TransactionStatus status) {
try {
template.insert("Tutorial.insertData", vo);
template.insert("Tutorial.updateData", vo);
return true;
}catch (Exception e){
e.printStackTrace();
status.setRollbackOnly();
return false;
}
}
});
return result;
}위와 같이 transactionTemplate.execute를 실행하고 전달인자로 TransactionCallBack 인스턴스를 전달하는데, 일반적으로 TransactionCallback이 인터페이스 이기 때문에 new로 객체를 생성하고 doInTransaction method를 구현합니다.
'Framework > SPRING FRAMEWORK' 카테고리의 다른 글
| [Spring Framework] @RequestParam을 사용하여 List형 데이터 받을때 주의점 (2) | 2013.11.14 |
|---|---|
| [Spring Framework] @Transactional로 구현한 트랜젝션에서 수동 rollback 하기 (5) | 2013.11.14 |
| Spring - Quartz를 사용하여 스케쥴러 구현하기 (12) | 2010.09.29 |
| Spring - get방식일때 한글 깨질때 해결 방법 (1) | 2009.10.26 |
| Spring - Spring의 Controller들. 3.MultiActionController (0) | 2009.09.13 |