티스토리 뷰

Web Development/Spring

Spring Transaction

dev ms 2016. 10. 27. 11:40
반응형

 스프링에서 선언적 트랜젝션은 만족할 만큼 세밀하지 못하다.
그렇다고 그 방법이 잘못된 것은 아니다.

우선 Transaction을 적용하는 방법은 Spring의 TransactionTemplate를 이용해 메소드에 트랜젝션 범위를 프로그래밍 하는 것이다.

TransactionTemplate도 콜백 메커니즘을 활용한다.

public void saveSpittle(final Spittle spittle) { transactionTemplate.execute(new TransactionCallback<Void>() { try{ spitterDao.saveSpittle(spittle); } catch (RuntimeException e) { txStatus.setRollbackOnly(); throw e; } return null; } }) }


TransactionCallback에는 구현할 메소드가 딱 하나뿐이므로 코드 6.2처럼 익명 내부 클래스 (anonymous inner class)로 구현하는 것이 가장 쉽다.
트랜잭션 제어 하에 실행될 코드를 doInTransaction() 메소드 내에 두기만 하면 된다.

TransactionTemplate 인스턴스의 execute()메소드를 호출하면 TransactionCallback객체에 담긴 코드가 실행된다. 만약 코드 실행 중 문제가 발생하면, TransactionStatus 객체의 setRollbackOnly() 메소드를 호출해서 트랜잭션을 롤백시킬 수 있다. 이와는 반대로 doInTransaction()이 별 문제없이 반환되면 트랜잭션은 커밋된다.


스프링의 선언적 트랜잭션 관리는 스프링 AOP 프레임워크를 통해 구현된다. AOP는 자연스러운 수순으로, 트랜잭션은 본래 애플리케이션의 주요 기능의 하부를 이루는 시스템 수준의 서비스이기 떄문이다. 스프링 사용자 입장에서는 스프링 트랜잭션을 트랜잭션 경계로 메소드를 '둘러치는(wrap)' 애스펙트로 생각하는 것이 가장 이해하기 쉽다.

스프링 설정에서 트랜잭션 경계를 선언하는 방식은 세 가지가 있다.
AOP와 TransactionProxyFactoryBean을 이용하여 빈마다 프록시를 만듦으로써 선언적 트랜잭션을 지원했으나,

스프링 2.0 이후부터 선호하는 방식은 스프링 tx 설정 네임스페이스를 이용하여 트랜잭션을 선언하는 방식과 @Transactional 애너테이션을 이용하는 방식이다.
그리고 현재 버전에서도 기존의 TransactionProxyFactoryBean은 여전히 유효하다.


선언적 트랜잭션은 전파방식, 격리 수준, 읽기전용 힌트, 타임아웃, 롤백 규칙으로 정의된다.

전파 방식.
호출되는 메소드와 클라이언트에 대하여 트랜잭션의 경계를 정의한다.


격리 수준
한 트랜잭션이 동시 진행 중인 다른 트랜잭션의 영향을 얼마나 받는가다.
따라서 자신의 트랜잭션 데이터에 대해 얼마나 이기적인 입장을 취하는 것이라 할 수 있다.


읽기 전용

데이터 저장소에 대해 오직 읽기 작업만 수행한다면, 데이터 저장소에서는 트랜잭션의 읽기 전용 특성을 활용한 몇 가지 최적화를 수행할 여지가 생긴다. 따라서 트랜잭션을 읽기전용으로 선언함으로써 데이터 저장소에게 최적화가 적절하다고 판단하고 최적화를 적용할 수 있는 기회를 줄 수 있다.


트랜잭션 타임아웃
트랜잭션이 무작정 오랜 시간 동안 수행돼서는 애플리케이션 성능이 제대로 나올 수 없다. 따라서 타임아웃(time out)도 선언적 트랜잭셔을 구성하는 또 하나의 요소다.

롤백 규칙

어떤 예외가 발생했을 때 롤백하고 어떤 경우에 그렇지 않은지를 정의하는 롤백 규칙(rollback rule)이다.
아무것도 정의하지 않았다면, 트랜잭션은 런타임 예외에 대해서는 로백하고 검사형 예외에서는 롤백하지 않는다??
(몰랏던 사실이다 =_=;)


반응형