<bean id="oracleTransactionManagerDataSource"
class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource"><ref bean="oracle_datasource"/></property>
</bean>
<tx:annotation-driven transaction-manager="oracleTransactionManagerDataSource"/>
// 메소드 실행중 EmpException이 발생한 경우 rollback을 수행하지 않음.
@Transactional(noRollbackFor={EmpException.class})
public void updateUserList(UserVO newUser, UserVO updateUser) throws EmpException {
String userName = "";
try {
userName = newUser.getUserName();
userDAO.addUser(newUser);
userName = updateUser.getUserName();
userDAO.updateUser(updateUser);
}
catch (Exception e) {
// 중략
}
}
| 속성 | 설명 |
| isolation | Transaction의 isolation Level 정의하는 요소. 별도로 정의하지 않으면 DB의 Isolation Level을 따름.
Isolation.DEFAULT, Isolation.READ_COMMITTED, Isolation.READ_UNCOMMITTED, Isolation.REPEATABLE_READ, Isolation.SERIALIZABLE 중 선택하여 정의할 수 있다. (Default = Isolation.DEFAULT) 각 Isolation Level에 대한 자세한 내용은 본 페이지의 [참고] Propagation Behavior, Isolation Level 를 참고하도록 한다. |
| noRollbackFor | 정의된 Exception 목록에 대해서는 rollback을 수행하지 않음. |
| noRollbackForClassname | Class 객체가 아닌 문자열을 이용하여 rollback을 수행하지 않아야 할 Exception 목록 정의 |
| propagation | Transaction의 propagation 유형을 정의하기 위한 요소.
Propagation.MANDATORY, Propagation.NESTED, Propagation.NEVER, Propagation.NOT_SUPPORTED, Propagation.REQUIRED, Propagation.REQUIRES_NEW, Propagation.SUPPORTS 중 선택하여 정의할 수 있다. (Default = Propagation.REQUIRED) 각 Propagation 유형에 대한 자세한 내용은 본 페이지의 [참고] Propagation Behavior, Isolation Level 를 참고하도록 한다. |
| readOnly | 해당 Transaction을 읽기 전용 모드로 처리 (Default = false) |
| rollbackFor | 정의된 Exception 목록에 대해서는 rollback 수행 |
| rollbackForClassName | Class 객체가 아닌 문자열을 이용하여 rollback을 수행해야 할 Exception 목록 정의 |
| timeout | 지정한 시간 내에 해당 메소드 수행이 완료되지 않은 경우 rollback 수행. -1일 경우 no timeout (Default = -1) |
<bean id="oracleTransactionManagerDataSource"
class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource"><ref bean="oracle_datasource"/></property>
</bean>
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd"> <tx:advice id="txAdvice" transaction-manager="oracleTransactionManagerDataSource"> <tx:attributes> <!-- 메소드 실행중 EmpException이 발생한 경우 rollback을 수행하지 않음 --> <tx:method name="*" no-rollback-for="com.sds.emp.common.EmpException"/> </tx:attributes> </tx:advice> <aop:config> <!-- pointcut 정의 : UserServiceImplWithXML 클래스의 모든 메소드 호출시 --> <aop:pointcut id="userServiceOperations" expression="execution(* com.sds.emp.user.services.impl.UserServiceImplWithXML.*(..))"/> <!-- advice 정의 : 위 tx 태그를 이용하여 정의한 advice 참조 --> <aop:advisor advice-ref="txAdvice" pointcut-ref="userServiceOperations"/> </aop:config>
| 속성 | 설명 |
| name | 메소드명. 와일드카드 사용 가능 |
| isolation | Transaction의 isolation Level을 정의하는 요소. 별도로 정의하지 않으면 DB의 Isolation 레벨을 따름.
DEFAULT, READ_COMMITTED, READ_UNCOMMITTED, REPEATABLE_READ, SERIALIZABLE 중 선택하여 정의할 수 있다. (Default = DEFAULT) 각 Isolation Level에 대한 자세한 내용은 본 페이지의 [참고] Propagation Behavior, Isolation Level 를 참고하도록 한다. |
| no-rollback-for | 정의된 Exception 목록에 대해서는 rollback을 수행하지 않음. |
| propagation | Transaction의 propagation 유형을 정의하기 위한 요소.
MANDATORY, NESTED, NEVER, NOT_SUPPORTED, REQUIRED, REQUIRES_NEW, SUPPORTS 중 선택하여 정의할 수 있다. (Default = REQUIRED) 각 Propagation 유형에 대한 자세한 내용은 본 페이지의 [참고] Propagation Behavior, Isolation Level 를 참고하도록 한다. |
| read-only | 해당 Transaction을 읽기 전용 모드로 처리. (Default = false) |
| rollback-for | 정의된 Exception 목록에 대해서는 rollback 수행 |
| timeout | 지정한 시간 내에 해당 메소드 수행이 완료되지 않은 경우 rollback 수행. -1일 경우 no timeout. (Default = -1) |
<bean id="oracleTransactionManagerDataSource"
class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource"><ref bean="oracle_datasource"/></property>
</bean>
<bean id="txConfig" abstract="true" class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean"> <property name="transactionManager" ref="oracleTransactionManagerDataSource"/> <property name="transactionAttributes"> <props> <prop key="*">PROPAGATION_REQUIRED,-java.lang.Exception, -anyframe.common.exception.BaseException, +com.sds.emp.common.EmpException</prop> </props> </property> </bean>
| transactionManager | 사용할 Transaction manager 속성을 정의한 Transaction Manager의 id를 참조한다. Transaction Manager 속성 정의 내용은 하단의 내용을 참고하도록 한다. | ||
| transactionAttributes |
target의 메소드 별로 transaction attributes를 정의할 수 있다. 여기에 Propagation Behavior, Isolation Level, "readOnly" flag, Rollback 규칙를
설정할 수 있다.(하단 '[참고] transactionAttributes 속성' 그림을 참고한다)
e.g. key ="myMethod", value ="PROPAGATION_REQUIRED,readOnly"
|
||
| target | TransactionProxyFactoryBean bean의 abstract attribute 값을 true로 놓고, 이 TransactionProxyFactoryBean bean을 parent로 정의한 bean 내에 target을 정의한다. |

<bean id="com.sds.emp.user.services.UserService" parent="txConfig"> <property name="target"> <bean class="com.sds.emp.user.services.impl.UserServiceImpl"> <property name="userDAO"> <bean class="com.sds.emp.user.services.impl.UserDAO"> <property name="queryService" ref="oracle_queryservice" /> <property name="propertiesService" ref="propertiesService" /> </bean> </property> </bean> </property> <property name="proxyInterfaces" value="com.sds.emp.user.services.UserService"/> </bean>
| PROPAGATION_MADATORY | 반드시 Transaction 내에서 메소드가 실행되야 하고,Transaction이 없는 경우에는 예외를 발생시킨다. |
| PROPAGATION_NESTED | Transaction에 있는 경우, 기존 Transaction 내의 nested transaction 형태로 메소드를 실행하고, nested transaction 자체적으로 commit, rollback이 가능하다. Transaction이 없는 경우, PROPAGATION_REQUIRED 속성으로 행동한다. |
| PROPAGATION_NEVER | Transaction 컨텍스트 없이 실행되어야 하며 Transaction이 있으면 예외를 발생시킨다. |
| PROPAGATION_NOT_SUPPORTED | Transaction 없이 메소드를 실행하며,기존의 Transaction이 있는 경우에는 이 Transaction을 호출된 메소드가 끝날 때까지 잠시 보류한다. |
| PROPAGATION_REQUIRED | Transaction 컨텍스트 내에서 메소드가 실행되어야 한다. 기존 Transaction이 있는 경우에는 기존 Transaction 내에서 실행하고, 기존 Transaction이 없는 경우에는 새로운 Transaction을 생성한다. |
| PROPAGATION_REQUIRED_NEW | 호출되는 메소드는 자신 만의 Transaction을 가지고 실행하고, 기존의 Transaction들은 보류된다. |
| PROPAGATION_SUPPORTS | 새로운 Transaction을 필요로 하지는 않지만, 기존의 Transaction이 있는 경우에는 Transaction 내에서 메소드를 실행한다. |
| ISOLATION_DEFAULT | 개별적인 PlatformTransactionManager를 위한 디폴트 격리 레벨 |
| ISOLATION_READ_COMMITTED | 이 격리수준을 사용하는 메소드는 commit 되지 않은 데이터를 읽을 수 없다. 쓰기 락은 다른 Transaction에 의해 이미 변경된 데이터는 얻을수 없다. 따라서 조회 중인 commit 되지 않은 데이터는 불가능하다. 대개의 데이터베이스에서의 디폴트로 지원하는 격리 수준이다. |
| ISOLATION_READ_UNCOMMITTED | 가장 낮은 Transaction 수준이다. 이 격리수준을 사용하는 메소드는 commit 되지 않은 데이터를 읽을 수 있다. 그러나 이 격리수준은 새로운 레코드가 추가되었는지 알수 없다. |
| ISOLATION_REPEATABLE_READ | ISOLATION_READ_COMMITED 보다는 다소 조금 더 엄격한 격리 수준이다. 이 격리 수준은 다른 Transaction이 새로운 데이터를 입력했다면, 새롭게 입력된 데이터를 조회할 수 있다는 것을 의미한다. |
| ISOLATION_SERIALIZABLE | 가장 높은 격리수준이다. 모든 Transaction(조회를 포함하여)은 각 라인이 실행될 때마다 기다려야 하기 때문에 매우 느리다. 이 격리수준을 사용하는 메소드는 데이터 상에 배타적 쓰기를 락을 얻음으로써 Transaction이 종료될 때까지 조회, 수정, 입력 데이터로부터 다른 Transaction의 처리를 막는다. 가장 많은 비용이 들지만 신뢰할만한 격리 수준을 제공하는 것이 가능하다. |
public void testUpdateUserWithNotExistUser() throws EmpException {
UserService userService = null;
try {
userService = (UserService) context.getBean("UserServiceWithAnnotation");
// 1. update user list
UserVO newUser = new UserVO();
newUser.setUserId("testuser");
// 중략
newUser.setRegDate(null);
UserVO updateUser = userService.getUser("woos41");
// 존재하지 않는 사용자 ID로 변경
updateUser.setUserId("woos");
String name = "woostest";
updateUser.setUserName(name);
// 신규 사용자 정보와 수정 대상 사용자 정보를 인자로 셋팅
userService.updateUserList(newUser, updateUser);
// 해당 메소드 수행시 에러가 발생하지 않으면 fail
throw new EmpException("fail to get user.");
} catch (EmpException e) {
try {
// 신규 사용자의 ID로 사용자 정보 조회
userService.getUser("testuser");
} catch (EmpException ee) {
// 사용자 정보 수정에 실패하였으나 Annotation 정의에 따라
// 신규 등록된 사용자 정보는 commit되었어야 함.
throw new EmpException("fail to manage transaction.");
}
}
}