728x90
Container managed 트랜잭션
Container-managed 트랜잭션
- 자바 엔터프라이즈 빈에서는 기본적으로 container-managed 트랜잭션을 사용한다
- 보통 메소드 시작시 트랜잭션 시작되고 메소드가 종료 직전에 commit된다
- 각 메소드는 single 트랜잭션이 된다
- Nested 혹은 멀티 트랜잭션은 메소드내에서 허용되지 않는다
- Container-mananged 트랜잭션에서는 트랜잭션에 관련 메소드가 필요하지 않다
- 그냥 필요한 빈 메소드가 트랜잭션 attribute를 붙혀주기만 하면된다 (@TransactionAttribute)
- 만약 트랜잭션을 컨트롤 하고 싶다면 application-managed 트랜잭션을 사용해야 한다
- Container-managed 트랜잭션을 사용하는 빈에서는 절대 트랜잭션 관리 메소드를 사용해서는 안된다.
java.sql.Connection의 commit, setAutoCommit, rollback 메소드
javax.jms.Session의 commit, rollback 메소드
javax.transaction.UserTransaction 인터페이스
Transaction Attributes
- Transaction Attribute는 트랜잭션의 scope을 정의한다
- scope은 매우 중요하다
- 메소드 A에 트랜잭션이 걸려 있을 때 내부에 있는 메소드 B에는 트랜잭션이 걸릴 것인가 혹은 새로운 트랜잭션을 사용할 것인가 결정할 수 있어야 한다
- 종류
Required
RequiresNew
Mandatory
NotSupported
Supports
Never
용어 정리
- Client : 다른 빈, 위 그림에서는 Bean1이 되겠다
1. Required
- Client가 트랜잭션을 시작하고 메소드를 실행한다면(T1), 메소드는 클라이언트 트랜잭션 내에서 실행된다. (T1)
- Client가 트랜잭션을 시작하지 않으면(None) 컨테이너 시작전 매소드는 새로운 트랜잭션을 실행한다 (T2)
- 모든 빈 메소드가 container-managed 트랜잭션에서 실행되도록 강제한다
- 다른 트랜잭션을 override하지 않는 이상은 required는 사용하지 않는다
2. RequiresNew
- 메소드가 항상 새로운 트랜잭션에서 호출하도록 할 때 사용
- Client가 트랜잭션 안에서 시작되고 메소드를 실행한다면(T1), 컨테이너는 다음과 같은 단계를 밟는다
- client의 트랜잭션을 지연시킨다
- 새로운 트랜잭션을 실행한다 (T2)
- 호출을 메소드에 위임한다
- 메소드가 완료되면 client 트랜잭션을 실행한다
- Client가 트랜잭션을 시작하지 않으면(None) 컨테이너 시작전 매소드는 새로운 트랜잭션을 시행한다 (T2)
3. Mandatory
- Client가 트랜잭션 안에서 시작되고 메소드를 실행한다면(T1), 클라이언트 트랜잭션 내에서 실행된다(T1)
- Client가 트랜잭션을 시작하지 않으면(None)
TransactionRequiredException
오류를 낸다 (Error) - 항상 Client 트랜잭션 안에서 실행하도록 강제할 때 사용
4. NotSupported
- Client가 트랜잭션 안에서 시작되고 메소드를 실행한다면(T1), 메소드를 실행하기 전까지 클라이언트의 트랜잭션을 지연시킨다 (None)
- 메소드가 완료되면 다시 클라이언트의 트랜잭션을 마저 시작한다
- Client가 트랜잭션을 시작하지 않으면(None), 메소드가 실행되기 전까지 새로운 트랜잭션을 실행하지 않는다(None)
- 트랜잭션이 필요하지 않을때 사용한다
- 왜냐하면 트랜잭션은 항상 오버헤드를 유발하므로 성능향상에 도움이 된다
5. Supports
- Client가 트랜잭션 안에서 시작되고 메소드를 실행한다면(T1), Client의 트랜잭션 내에서 메소드가 실행된다(T1)
- Client가 트랜잭션을 시작하지 않으면(None), 메소드가 실행되기 전까지 새로운 트랜잭션을 실행하지 않는다(None)
6. Never
- Client가 트랜잭션 안에서 시작되고 메소드를 실행한다면(None),
RemoteException
오류를 낸다(Error) - Client가 트랜잭션을 시작하지 않으면(None), 메소드가 실행되기 전까지 새로운 트랜잭션을 실행하지 않는다(None)
요약
- T1, T2는 컨테이너에 의한 트랜잭션
- T1은 Client와 관련된 트랜잭션
- 보통 Client는 다른 빈을 지칭한다
- 내부에 메소드가 실행된다
- T2 트랜잭션은 메소드가 실행되기 전에 컨테이너에 의해 실행된다
- None은 컨테이너의 의해 실행되는 트랜잭션 내에서 메소드가 실행되지 않는다는 뜻
Transaction Attribute 세팅
- 클래스나 메소드에
javax.ejb.TransactionAttribute
어노테이션을 사용한다 javax.ejb.TransactionAttributeType
을 사용한다- NOT_SUPPORTED, REQUIRED....
- 만약 클래스에
TransactionAttribute
를 사용하면 클래스 내부의 모든 메소드에 적용된다 - 만약 메소드에
TransactionAttribute
를 사용하면 해당 메소드에만 적용된다 - 둘다 적용되면 메소드는 Override한다
@TransactionAttribute(NOT_SUPPORTED)
@Stateful
public class TransactionBean implements Transaction {
...
@TransactionAttribute(REQUIRES_NEW)
public void firstMethod() {...}
@TransactionAttribute(REQUIRED)
public void secondMethod() {...}
public void thirdMethod() {...}
public void fourthMethod() {...}
}
- firstMethod 실행시
- 무조건 새로운 트랜잭션 생성
- secondMethod 실행시
- 현재 트랜잭션을 사용하거나, 트랜잭션없으면 새로운 트랜잭션 사용
- thirdMethod 실행시
- 무조건 트랜잭션을 실행하지 않는다
TransactionAttributeType
Rollback
- Container-Managed 트랜잭션은 두가지 방법이 있다
- System Exception 오류가 발생할 경우 자동으로 rollback 실행
- EJBContext 인터페이스의 setRollbackOnly 메소드를 실행할 경우
- 어플리케이션 오류가 난 경우는 자동으로 rollback하지 않으므로 명시적으로 rollback 해야한다
세션 빈의 인스턴스 변수 Syncronizing
- SessionSynchronization 인터페이스는 트랜잭션 동기화 알림을 받기 위해 session 빈 인스턴스를 허용한다
- 빈의 인스턴스 변수와 데이터베이스 값을 동기화 할 수 있다는 뜻이다
- 컨테이너가 각 트랜잭션 스테이지에서 SessionSynchronization 메소드 (afterBegin, beforeCompletion, afterCompletion)를 실행한다
- afterBegin
- 인스턴스에게 새로운 트랜잭션이 실행되었다고 알린다
- 메소드 실행하기 직전에 컨테이너가 afterBegin을 실행한다
- beforeCompletion
- 컨테이너는 beforeCompletion을 메소드 끝난 직후, 트랜잭션 commit 직전에 실행한다
- beforeCompletion는 session 빈이 롤백하기 위한 마지막 기회이다 (setRollbackOnly를 호출)
- afterCompletion
- 트랜잭션이 끝났다는 것을 알림
- commit 되었다면 true, rollback되면 false 파라미터를 가진다
Container-Manged 트랜잭션을 허용하지 않는 메소드
- 컨테이너가 지정한 트랜잭션 바운더리에 아래 메소드를 절대 사용하지 않는다
- 왜냐면 해당 메소드들은 application-managed 트랜잭션이기 때문이다
java.sql.Connection의 commit, setAutoCommit, rollback
javax.ejb.EJBContext의 getUserTransaction()
javax.transaction.UserTransaction의 메소드들
정리
- 트랜잭션은 scope이 매우 중요하다
- scope은 빈의 메소드 내부에서 실행되는 다른 빈의 메소드에 현재 트랜잭션의 파생 여부를 결정
- @TransactionAttribute에는 여러 scope이 존재한다
Required
RequiresNew
Mandatory
NotSupported
Supports
Never
728x90