spring transaction 정리문서
예전 스터디 발표용으로 정리했던 문서
Spring Transaction 구현
1. Transaction 기본 개념
1) 트랜잭션?
- ATM, 데이터베이스 등의 시스템에서 사용되는 쪼갤 수 없다는 업무처리의 단위이다.
데이터베이스 에서 모든 데이터는 트랜잭션에 의해 변경된다.
2) ACID?
1) 원자성(atomicity) : 트랜잭션은 전부, 전무의 실행만이 있지 일부 실행으로
트랜잭션의 기능을 가질 수는 없다.
2) 일관성(consistency) : 트랜잭션이 그 실행을 성공적으로 완료하면 언제나 일관된
데이터베이스 상태로 된다.
3) 격리성(isolation) : 연산의 중간결과에 다른 트랜잭션이나 작업이 접근할 수 없다.
4) 영속성(durability) : 트랜잭션의 일단 그 실행을 성공적으로 끝내면 그 결과를 어떠한
경우에라도 보장받는다.
2. Spring JDBC를 이용한 트랜잭션
# applicationContext.xml 내용
<!—JDBC dataSource 세팅 -->
...............
<!-- TransactionManager -->
<bean id="transactionManager"
class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource" />
</bean>
<bean id="transactionTemplate"
class="org.springframework.transaction.support.TransactionTemplate"
p:transactionManager-ref="transactionManager" />
<bean id="placeOrderService" class="kame.spring.store.domain.PlaceOrderServiceTransactionTemplateImpl"
p:transactionTemplate-ref="transactionTemplate"
................
/>
# PlaceOrderServiceTransactionTemplateImple.class
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.support.TransactionCallback;
import org.springframework.transaction.support.TransactionTemplate;
........
private TransactionTemplate transactionTemplate;
@Override
public PurchaseOrderResult order(final PurchaseOrderRequest orderRequest)
throws ItemNotFoundException {
Object orderResult = transactionTemplate.execute(
new TransactionCallback() {
@Override
public Object doInTransaction(TransactionStatus status) {
try {
testDao.insert(~~~~);
testDao.insert2(~~~~);
} catch(Exception e) {
status.setRollbackOnly();
}
.......
// Runtime error 시엔 자동으로 Rollback 이 일어난다.
}});
}
3. 선언적 트랜잭션 처리
1) <tx:advice> 태그 이용
# applicationContext.xml 내용
<!-- declare transaction example -->
<tx:advice id="txAdvice" transaction-manager="transactionManager">
<tx:attributes>
<tx:method name="order" propagation="REQUIRED" />
<tx:method name="get*" read-only="true" />
<tx:method name="regist" rollback-for="Exception"
no-rollback-for="MemberNotFoundException" />
</tx:attributes>
</tx:advice>
<!-- aop 세팅 -->
<aop:config>
<aop:pointcut id="txPointcut"
expression="execution(public * transaction.domain.*Service.*(..))" />
<aop:advisor advice-ref="txAdvice" pointcut-ref="txPointcut" />
</aop:config>
# <tx:method> 규칙 (그외 xml 코딩 규칙은 책 참고)
속 성 명 |
설 명 |
name |
트랜잭션이 적용될 메서드 이름 명시한다. |
propagation |
트랜잭션 전파 규칙 설정 |
isolation |
트랜잭션 격리 레벨 설정 (보통 : DEFAULT) |
read-only |
읽기 전용 여부 설정 |
no-rollback-for |
트랜잭션을 롤백하지 않을 예외 타입 설정 |
rollback-for |
트랜잭션을 롤백 할 예외 타입 설정 |
timeout |
트랜잭션의 타임 아웃 시간 설정 (초단위) |
2) TransactionProxyFactoryBean을 이용한 트랜잭션 처리
# applicationContext.xml 내용
<bean id=”placeOrderService” class=”org.springframework.transaction.interceptor.TransactionProxyFactoryBean”>
<property name=”target”>
<bean class=”kame.spring.store.domain.PlaceOrderServiceImpl”
p:itemDao-ref=”itemDao” p:paymentInfoDao-ref=”paymentInfoDao”
p:purchaseOrderDao-ref=”purchaseOrderDao” />
</property>
<property name=”transactionManager” ref=”transactionManager” />
<property name=”transactionAttributes”>
<props>
<prop key=”order”>PROPAGATION_REQUIRED</prop>
<prop key=”get*”>PROPAGATION_REQUIRED, readOnly</prop>
</props>
</property>
</bean>
3) annotation 기반 트랜잭션 설정
# applicationContext.xml 내용
<tx:annotation-driven transaction-manager="txManager"/>
# business단 내용
@Transactional(readOnly = true)
public class DefaultFooService implements FooService {
public Foo getFoo(String fooName) {
-- 비지니스 로직
}
@Transactional(readOnly = false, propagation = Propagation.REQUIRES_NEW)
public void updateFoo(Foo foo) {
-- 비지니스 로직
}
4. 기타 트랜잭션 처리
1) Spring – Sqlmap 연동 트랜잭션 처리
try {
getSqlMapClientTemplate().getSqlMapClient().startTransaction();
getSqlMapClientTemplate().getSqlMapClient().getCurrentConnection().setAutoCommit( false );
getSqlMapClientTemplate().getSqlMapClient().commitTransaction();
getSqlMapClientTemplate().update("modify1", param);
getSqlMapClientTemplate().update("modify2", param);
getSqlMapClientTemplate().getSqlMapClient().getCurrentConnection().commit();
getSqlMapClientTemplate().getSqlMapClient().endTransaction();
} catch ( Exception e ) {
e.printStackTrace();
throw new RuntimeException();
}
2) Sqlmap 자체 트랜잭션 처리
# Select
sqlMap.startTransaction();
List list = sqlMap.queryForList (“getProductList”, hm);
sqlMap.endTransaction();
# Update
sqlMap.startTransaction();
sqlMap.insert("setProductList ",hm);
sqlMap.commitTransaction();
sqlMap.endTransaction();