public void updateUserList(UserVO newUser, UserVO updateUser) throws EmpException {
String userName = "";
try {
transactionManager.begin();
userName = newUser.getUserName();
userDAO.addUser(newUser);
userName = updateUser.getUserName();
userDAO.updateUser(updateUser);
transactionManager.commit();
}
catch (Exception e) {
transactionManager.rollback();
// 중략
}
}
// 메소드 실행중 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) {
// 중략
}
}
| Parameter | Description |
| isolation | 트랜잭션의 isolation 레벨 정의하는 요소. 별도로 정의하지 않으면 DB의 Isolation 레벨을 따름. |
| noRollbackFor | 정의된 Exception 목록에 대해서는 rollback을 수행하지 않음. |
| noRollbackForClassname | Class 객체가 아닌 문자열을 이용하여 rollback을 수행하지 않아야 할 Exception 목록 정의 |
| propagation | 트랜잭션의 propatation 유형 정의 |
| readOnly | 해당 트랜잭션을 읽기 전용 모드로 처리 |
| rollbackFor | 정의된 Exception 목록에 대해서는 rollback 수행 |
| rollbackForClassName | Class 객체가 아닌 문자열을 이용하여 rollback을 수행해야 할 Exception 목록 정의 |
| timeout | 지정한 시간 내에 해당 메소드 수행이 완료되지 않은 경우 rollback 수행. -1일 경우 no timeout |
<bean id="transactionManagerDataSource"
class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource"><ref bean="common_datasource"/></property>
</bean>
<tx:annotation-driven transaction-manager="transactionManagerDataSource"/>
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.");
}
}
}
<tx:advice id="txAdvice" transaction-manager="transactionManagerDataSource"> <tx:attributes> <!-- 메소드 실행중 EmpException이 발생한 경우 rollback을 수행하지 않음 --> <tx:method name="*" no-rollback-for="com.sds.emp.common.EmpException"/> </tx:attributes> </tx:advice> <aop:config> <!-- pointcut 정의 : UserServiceImplWithXML 클래스의 updateUserList 메소드 호출시 --> <aop:pointcut id="updateUserList" expression="execution(* com.sds.emp.user.services.impl.UserServiceImplWithXML.updateUserList(..))"/> <!-- advice 정의 : 위 tx 태그를 이용하여 정의한 advice 참조 --> <aop:advisor advice-ref="txAdvice" pointcut-ref="updateUserList"/> </aop:config>
| Parameter | Description |
| name | 메소드명. 와일드카드 사용 가능 |
| isolation | 트랜잭션의 isolation 레벨(DEFAULT, READ_COMMITTED, READ_UNCOMMITTED, REPEATABLE_READ, SERIALIZABLE) 정의하는 요소. 별도로 정의하지 않으면 DB의 Isolation 레벨을 따름. |
| no-rollback-for | 정의된 Exception 목록에 대해서는 rollback을 수행하지 않음. |
| propagation | 트랜잭션의 propatation 유형(MANDATORY, NESTED, NEVER, NOT_SUPPORTED, REQUIRED, REQUIRES_NEW, SUPPORTS) 정의. 기본값은 REQUIRED |
| read-only | 해당 트랜잭션을 읽기 전용 모드로 처리. 기본값은 false |
| rollback-for | 정의된 Exception 목록에 대해서는 rollback 수행 |
| timeout | 지정한 시간 내에 해당 메소드 수행이 완료되지 않은 경우 rollback 수행. -1일 경우 no timeout. 기본값은 -1 |
<bean id="transactionManagerDataSource"
class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource"><ref bean="common_datasource"/></property>
</bean>
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) {
// 사용자 정보 수정에 실패하였으나 트랜잭션 속성 정의에 따라
// 신규 등록된 사용자 정보는 commit되었어야 함.
throw new EmpException("fail to manage transaction.");
}
}
}
| Method Name | Return Type | Parameters |
| getUserList | com.sds.emp.common.Page | com.sds.emp.user.services.SearchVO |
| getUser | com.sds.emp.user.services.UserVO | java.lang.String |
| addUser | void | com.sds.emp.user.services.UserVO |
| updateUser | void | com.sds.emp.user.services.UserVO |
| checkDuplication | boolean | java.lang.String |
| updateUserList | void | com.sds.emp.user.services.UserVO, com.sds.emp.user.services.UserVO |
| anyframe-aoptest-transaction-src.zip |