Spring @Transactional 주의사항 및 propagation( Required, Nested, Requires_new)차이에 대해서..
- Transactional사용시 주의사항
* junit에서 테스트용으로 돌리다 보면, 아래와 같은 케이스가 있는데 이럴 때 주의할 사항.
--------------------------------
class A {
@Transactional
void aa() {
}
void bb() {
aa();
}
}
--------------------------------
junit에서 위와 같이 transactional이 걸려있는 메소드(aa();)를 호출하는 메소드(bb())에 대해서 transaction 테스트를 하려고 하면 transaction이 정상동작하지 않음(rollback 안됨 현상)... (proxy기반이라 하나의 클래스의 진입점 transaction을 따르는 거 같음... @.@ ) 즉, 테스트 대상 bb();에 @Transactoinal이 걸려 있어야 하는 듯...
- Propagation (기본적으로 spring propagation은 Exception을 기본으로 동작(즉, 내부에서 exception이 발생하는 것을 바탕으로 rollback할지 여부 결정하는 듯..))
* Required : 가장 기본 transaction으로 trasaction 연결이 하나의 connection안에서 동작하며, 계속해서 required가 붙으면 붙을 수록 각 요청을 기록해두었다가 하나라도 exception이 발생하면 모두 rollback되는 Propagation
* nested : 제일 헷갈렸는데, nested로 기존 transaction안에서 실행되나, nested안에서 exception 발생시에는 자기것만 rollback하는 듯.. ( 단, 해당 exception을 내부 로직단에서 catch해서 뭔가 후처리가 있어야 함... 없으면 exception이 계속 상위로 전달되서 상위 transaction까지 영향을 미칠 수 있음)
** Required에서는 아무리 하위 transaction을 try, catch로 묶어도 proxy단에서 exception을 발생하기 때문에 중첩구조에서 하나라도 실패하면 그대로 rollback되나, nested로 한후 이를 try, catch로 묶으면 개별 컨트롤 가능한 듯... @.@
* Requires_New : 이거는 아예 새로 transaction을 만들기 때문에 중첩된 transaction구조에서 자신 메소드가 아닌, 다른 곳에서 exception이 발생하더라도 자기꺼는 rollback안하는 듯... 또, 자기것만 exception발생하는 걸 다른곳으로 전파 안할 수 있음..
** nested랑 차이는 nested는 상위 transaction에 일단 다같이 묶인 상태에서 자기만 별도로 존재하기 때문에 상위가 rollback되면 자기도 rollback되나 requires_new는 상위가 rollback되도 자기는 안하게 할 수 있는 듯...
따라서 Transaction Propagation 테스트할 때는 try, catch를 잘 이용해서 transaction범위에 어떻게 정해지는지 확인후에 작업해야 할 듯..
* junit에서 테스트용으로 돌리다 보면, 아래와 같은 케이스가 있는데 이럴 때 주의할 사항.
--------------------------------
class A {
@Transactional
void aa() {
}
void bb() {
aa();
}
}
--------------------------------
junit에서 위와 같이 transactional이 걸려있는 메소드(aa();)를 호출하는 메소드(bb())에 대해서 transaction 테스트를 하려고 하면 transaction이 정상동작하지 않음(rollback 안됨 현상)... (proxy기반이라 하나의 클래스의 진입점 transaction을 따르는 거 같음... @.@ ) 즉, 테스트 대상 bb();에 @Transactoinal이 걸려 있어야 하는 듯...
- Propagation (기본적으로 spring propagation은 Exception을 기본으로 동작(즉, 내부에서 exception이 발생하는 것을 바탕으로 rollback할지 여부 결정하는 듯..))
* Required : 가장 기본 transaction으로 trasaction 연결이 하나의 connection안에서 동작하며, 계속해서 required가 붙으면 붙을 수록 각 요청을 기록해두었다가 하나라도 exception이 발생하면 모두 rollback되는 Propagation
* nested : 제일 헷갈렸는데, nested로 기존 transaction안에서 실행되나, nested안에서 exception 발생시에는 자기것만 rollback하는 듯.. ( 단, 해당 exception을 내부 로직단에서 catch해서 뭔가 후처리가 있어야 함... 없으면 exception이 계속 상위로 전달되서 상위 transaction까지 영향을 미칠 수 있음)
** Required에서는 아무리 하위 transaction을 try, catch로 묶어도 proxy단에서 exception을 발생하기 때문에 중첩구조에서 하나라도 실패하면 그대로 rollback되나, nested로 한후 이를 try, catch로 묶으면 개별 컨트롤 가능한 듯... @.@
* Requires_New : 이거는 아예 새로 transaction을 만들기 때문에 중첩된 transaction구조에서 자신 메소드가 아닌, 다른 곳에서 exception이 발생하더라도 자기꺼는 rollback안하는 듯... 또, 자기것만 exception발생하는 걸 다른곳으로 전파 안할 수 있음..
** nested랑 차이는 nested는 상위 transaction에 일단 다같이 묶인 상태에서 자기만 별도로 존재하기 때문에 상위가 rollback되면 자기도 rollback되나 requires_new는 상위가 rollback되도 자기는 안하게 할 수 있는 듯...
따라서 Transaction Propagation 테스트할 때는 try, catch를 잘 이용해서 transaction범위에 어떻게 정해지는지 확인후에 작업해야 할 듯..
댓글
댓글 쓰기