기본 base가 되는 table이 있고, 그 테이블에 대한 이력을 저장하는 history테이블이 있을 경우, base가 insert가 성공하고, history에서 에러가 발생할 경우 rollback이 되지 않는 문제가 있어서 여러가지 테스트를 해 본 결과이다.
1. 컨트롤러에서 base와 history 두개의 service를 가져와서 처리하는 경우 rollback이 되지 않는다.
서비스단에서 @Transactional 를 주고 처리를 해야 rollback이 된다.
2.Transactional 어노테이션은 클래스에 줘도 적용된다.
3. 이 부분 때문에 고생했다.
아래와 같이 강제로 익셉션을 발생시키면서 try catch로 잡으면 rollback이 안된다.
아래와 같이 메소드에서 throws Exception을 해 줘야 한다.
이 때 강제로 발생시키는 익셉션은 (rollbackFor = Exception.class) 옵션을 줘야 rollback이 된다.
@Transactional(rollbackFor = Exception.class)
public class CompanyRoleService extends GenericService<CompanyRole, CompanyRoleRequest> {
...
public int saveWithHistory(CompanyRole object) throws Exception {
AddBaseEntity.addCreatedBy(object);
object.setUseYn("Y");
object.setDeleteYn("N");
int baseSuccessCount = baseMapper.insert(object);
if(baseSuccessCount>0){
throw new Exception("test");
}
...
2019.07.26 추가.
4. try catch로 롤백 하는 방법
https://stackoverflow.com/questions/25738883/spring-transactional-annotation-when-using-try-catch-block
메소드에 선언.
@Transactional(rollbackFor={MyException1.class, MyException2.class, ....})
public Result doStuff(){
...
}
or
프로그램 방식으로 rollback
public Result doStuff(){
try {
// business logic...
} catch (Exception ex) {
// trigger rollback programmatically
TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
}
}
public Result doStuff(){
...
}
or
프로그램 방식으로 rollback
public Result doStuff(){
try {
// business logic...
} catch (Exception ex) {
// trigger rollback programmatically
TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
}
}