1. Transaction이란?
여러 과정을 하나의 행위로 묶을 때 사용된다.
여러 단계를 수행했을때, 하나라도 실패하면 모두 취소되어야 한다.
이렇게 함으로써 데이터의 무결성을 보장한다. 모두 반영하거나 반영하지 않음.
2.Transaction을 쓰는이유?
Transaction을 관리하기위해 쓰이며 Spring에서는 SqlSession으로 commit, rollback 이 불가 그래서 Transaction을 이용하여 commit과 rollback을 진행한다. TransactionStatus객체가 있으며 어떻게 트랜잭션할것건지 설정을 transactionManager을 이용한다. DefaultTransactionDefinition은 transaction설정정보를 담고있다.
3. 트랜잭션에 대한 설정 정보를 담고 있는 객체
•
DefaultTransactionDefinition def = new DefaultTransactionDefinition();
전파 행위옵션
* REQUIRED : 진행중인 트랜잭션이 있으면 현재 메서드를 그 트랜잭션에서 실행하되 그렇지 않은 경우 새 트랜잭션을 시작해서 실행한다.
*
* REQUIRED_NEW : 항상 새 트랜잭션을 시작해 메서드를 실행하고 진행중인 트랜잭션이 있으면 잠시 중단시킨다.
*
* SUPPORTS : 진행중인 트랜잭션이 있으면 현재 메서드를 그 트랜잭션 내에서 실행하되, 그렇지 않을 경우 트랜잭션 없이 실행한다.
*
* NOT_SUPPORTED : 트랜잭션 없이 현재 메서드를 실행하고 진행중인 트렌잭션이 있으면 잠시 중단한다.
*
* MANDATORY : 반드시 트랜잭션을 걸고 현재 메서드를 진행중인 트랜잭션이 없으면 예외를 던진다.
*
* NEVER : 반드시 트랜잭션없이 현재 메서드를 실행하되 진행 중인 트랜잭션이 있으면 예외를 던진다.
*
* NESTED : 진행중인 트랜잭션이 있으면 현재 메서드를 이 트랜잭션의 중첩트랜잭션 내에서 실행한다. 진행중인 트랜잭션이 없으면 새 트랜잭션을 실행한다.
* 배치 실행 도중 처리해야할 업무가 백만개라고 하면 10만개씩 끊어서 커밋하는 경우
* 중간에 자못되어도 중첩 트랜잭션을 롤백하면 전체가아닌 10만개만 롤백된다.
* (세이브포인트를 이용하는 방식이다. 따라서 세이브 포인트를 지원하지 않는 경우 사용이 불가능하다.)
* */
def.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED);
격리 레벨 ( 동시성 고려 )
* DEFAULT: DB의 기본 격리 수준을 사용한다. 대다수는 READ_COMMITTED가 기본 격리 수준이다.
*
* READ_UNCOMMITTED : 다른 트랜젝션이 아직 커밋하지 않은 값을 또 다른 트랜잭션이 읽을 수 있다.
* 따라서 오염된 값을 읽거나, 재현 불가능한 읽기, 허상읽기 등의 문제가 발생할수 있다.
*
* READ_COMMITED : 트랜잭션이 다른 트랜잭션에서 커밋한 값만 읽을 수 있다.
* 오염된 값 읽기 문제는 해결되지만 재현 불가능한 읽기 및 허상 읽기는 여전히 발생할 수 있다.
*
* REPEATABLE_READ : 트랜잭션이 어떤 필드를 여러번 읽어도 동일한 값을 읽도록 보장한다.
* 트랜잭션이 지속되는 동안에는 다른 트랜젝션이 해당 필드를 변경할 수 없다
* 오염된 값읽기, 재현 불가능한 읽기문제는 해결되지만 허상읽기는 여전히 발생할 수 있다.
*
* SERIALIZABLE : 트랜잭션이 테이블을 여러번 읽어도 정확히 동일한 로우를 읽도록 보장한다.
* 트랜잭션이 지속되는 동안에는 다른 트랜잭션이 해당 테이블에 삽입, 수정, 삭제를 할 수 없다.
* 동시성 문제는 모두 해소되지만 성능은 현저하게 떨어진다.
*
* 오염된 값 : 하나의 트랜젝션이 데이터를 변경 후 잠시 기다리는 동안 다른 트랜젝션이 데잍를 읽게된다면
* 격리 레벨이 READ_UNCOMMITTED인 경우 아직 변경 후 커밋하지 않은 재고 값을 그대로 읽게 된다.
* 그러나 처음 트랜젝션이 데이터를 롤백하게되면 다른 트렌젝션이 읽은 값은 더 이상 유효하지 않은 일시적인 값이 된다.
* 이것을 오염된 값이라고 한다.
*
* 재현 불가능한 읽기 : 처음 트랜젝션이 데이터를 수정하면 수정이되고 아직 커밋되지 않은 로우에 수정 잠긍믈 걸어둔 상태이다.
* 결국 다른 트랜잭션은 이 트랜젝션이 커밋 혹은롤백되고 수정 잠금이 풀릴 때 까지 기다렷다가 읽을 수 밖에 없게 된다.
* 하지만 다른 로우에 대해서는 또 다른 트랜잭션이 데이터를 수정하고 커밋을 하게 되면
* 가장 처음에 동작한 트랜잭션이 데이터를 커밋하고 다시 조회를 한 경우 처음 읽은 그 값이 아니게 된다.
* 이것이 재현 불가능한 읽기이다.
*
* 허상 읽기 : 처음 트랜잭션이 테이블에서 여러 로우를 읽은 후 이후 트랜젝션이 같은 테이블의 로우를 추가하는 경우
* 처음 트랜잭션이 같은 테이블을 다시 읽으면 자신이 처음 읽었을 때와 달리 새로 추가된 로우가 있을 것이다.
* 이것을 허상읽기라고한다. (재현 불가능한 읽기와 유사하지만 허상읽기는 여러 로우가 추가된느 경우를 말한다.)
* */
def.setIsolationLevel(DefaultTransactionDefinition.ISOLATION_SERIALIZABLE);
/*트랜잭션에 대한 실행을 제어하거나 트랜잭션 상태 등을 조회할 수 있는 간단한 방법을 제공하는 객체*/
TransactionStatus status = transactionManager.getTransaction(def);
HTML
복사
4. Aop를 이용한 트랜잭션
AOP를 이용한 트랜잭션은 javaconfig방식과 xmlconfig방식이 있다
4-1 . javaconfig방식
xml쪽에 AOP와 transaction선언 해주기
트랜잭션을 선언해주면 class쪽에 어노테이션을 이용하여 트랜잭션을 사용할 수 있다.
4-2 xmlConfig방식
xml방식에서는 transaction과 AOP설정을 다해주는 방식이다.
5. readOnly 속성
•
트랜잭션을 읽기 전용으로 설정할 수 있다.-
•
성능을 최적화하기 위해 사용할 수도 있고 특정 트랜잭션 작업 안에서 쓰기 작업이 일어나는 것을 의도적으로 방지하기 위해 사용할 수도 있다.
•
일부 트랜잭션 매니저의 경우 읽기전용 속성을 무시하고 쓰기 작업을 허용할 수도 있기 때문에 주의해야 한다.-
•
일반적으로 읽기 전용 트랜잭션이 시작된 이후 INSERT, UPDATE, DELETE 같은 쓰기 작업이 진행되면 예외가 발생한다.
•
aop/tx 스키마로 트랜잭션 선언을 할 때는 이름 패턴을 이용해 읽기 전용 속성으로 만드는 경우가 많다. 보통 get이나 find 같은 이름의 메소드를 모두 읽기전용으로 만들어 사용하면 편리하다.
•
@Transactional 의 경우는 각 메소드에 일일이 읽기 전용 지정을 해줘야 한다.
•
read-only 애트리뷰트 또는 readOnly 앨리먼트로 지정한다.
•
true인 경우 insert, update, delete 실행 시 예외 발생, 기본 설정은 false
ex)@Transactional(readOnly = true)
6. 트랜잭션 롤백 예외(rollback-for, rollbackFor, rollbackForClassName)
•
선언적 트랜잭션에서는 런타임 예외가 발생하면 롤백한다.
•
반면에 예외가 전혀 발생하지 않거나 체크 예외가 발생하면 커밋한다.
•
체크 예외를 커밋 대상으로 삼은 이유는 체크 예외가 예외적인 상황에서 사용되기보다는 리턴 값을 대신해서 비즈니스적인 의미를 담은 결과를 돌려주는 용도로 많이 사용되기 때문이다.-
•
스프링에서는 데이터 액세스 기술의 예외는 런타임 예외로 전환돼서 던져지므로 런타임 예외만 롤백 대상으로 삼은 것이다.
•
하지만 기본 동작방식을 바꿀 수도 있다.
ex ) 체크 예외지만 롤백 대상으로 삼아야 하는 것이 있다면 XML의 rolback-for 애트리뷰트나 애노테이션의 rollbackFor 또는 rollbackForClassName 앨리먼트를 이용해서 예외를 지정하면 된다.
•
rollback-for 나 rollbackForClassName 은 예외 이름을 넣으면 되고, rollbackFor 는 예외 클래스를 직접 넣는다.
•
@Transactional 에서는 다음과 같이 클래스 이름 대신 클래스를 직접 사용해도 된다.
•
@Transactional(readOnly=true, rollbackFor=NoSuchMemberException.class)
rollbackFor 속성
특정 예외가 발생 시 강제로 Rollback
설정 예: @Transactional(rollbackFor=Exception.class)
noRollbackFor 속성
특정 예외의 발생 시 Rollback 처리되지 않음
설정 예: @Transactional(noRollbackFor=Exception.class)
[갓대희의 작은공간]
7. timeout속성
•
지정한 시간내에 해당 메소드 수행이 완료되지 않은 경우 rollback 수행 -1일 경우 no timeout(Default=-1)
•
ex)@Transactional(timeout=10)