프로젝트를 진행하다 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 |