[spring] Spring 에서의 트랜잭션 정리

[spring] Spring 에서의 트랜잭션 정리

트랜잭션이란 흔히 데이터 베이스에서 등장하는 용어인데, 스프링에서도 트랜잭션은 어떻게 사용되어지고 있는지 정리 해 보도록 하겠습니다.

트랜잭션이란

먼저 트랜잭션(Transaction)의 정의를 검색 해 보면 데이터베이스의 상태를 변환시키는 하나의 논리적 기능을 수행하기 위한 작업의 단위 또는 한꺼번에 모두 수행되어야 할 일련의 연산들을 의미한다. 라고 나옵니다.

이해가 더 잘되기 위해서는 트랜잭션이 왜 쓰이고 필요한지에 대해서 생각 해 보면 됩니다.

만약 데이터베이스의 데이터를 수정하는 도중에 오류가 발생된다면 DB의 데이터들은 수정이 되기 전의 상태로 다시 되돌아가져야 하고, 다시 수정 작업이 진행되어야 할 것입니다.

이렇듯 여러 작업을 진행하다가 문제가 생겼을 경우 이전 상태로 롤백하기 위해 사용되는 것이 트랜잭션(Transaction) 입니다.

Spring에서의 트랜잭션

스프링에서는 트랜잭션이 크게 프로그래밍 방식과 선언적 방식으로 나뉩니다.

1. 선언적 트랜잭션

클래스나 메서드 위에 @Transactional을 적어주면, 해당 클래스나 메서드가 트랜잭션 기능이 적용된 프록시 객체가 생성됩니다.

이 프록시 객체는 @Transactional이 포함된 메서드가 호출될 경우, PlatformTransactionManager를 사용하여 트랜잭션을 시작하고, 정상 여부에 따라 Commit 또는 Rollback을 합니다.

2. 프로그래밍적 트랜잭션

스프링에서는 프로그래밍 방식 트랜잭션 관리에 있어서 TransactionTemplate 사용을 권장하므로 TransactionTemplate 를 자세히 알아보겠습니다.

트랜잭션 컨텍스트에서 실행하면서 TransactionTemplate 을 사용하는 애플리케이션 코드는 다음과 같습니다.

TransactionCallback 구현체는 트랜잭션 컨텍스트에서 실행 할 코드를 작성 한다. -> 커스텀 TransactionCallback 의 인스턴스를 TransactionTemplate의 excute() 메서드로 전달합니다.

public class SimpleService implements Service { // single TransactionTemplate shared amongst all methods in this instance private final TransactionTemplate transactionTemplate; // use constructor-injection to supply the PlatformTransactionManager public SimpleService(PlatformTransactionManager transactionManager) { Assert.notNull(transactionManager, "The 'transactionManager' argument must not be null."); this.transactionTemplate = new TransactionTemplate(transactionManager); } public Object someServiceMethod() { return transactionTemplate.execute(new TransactionCallback() { // the code in this method executes in a transactional context public Object doInTransaction(TransactionStatus status) { updateOperation1(); return resultOfUpdateOperation2(); } }); } }

반환값이 없다면 TransactionCallbackWithoutResult 클래스를 사용합니다.

transactionTemplate.execute(new TransactionCallbackWithoutResult() { protected void doInTransactionWithoutResult(TransactionStatus status) { updateOperation1(); } });

콜백 안의 코드는 파라미터로 제공된 TransactionStatus 객체의 setRollbackOnly() 메서드를 호출하여 트랜잭션을 롤백할 수 있습니다.

transactionTemplate.execute(new TransactionCallbackWithoutResult() { protected void doInTransactionWithoutResult(TransactionStatus status) { try { updateOperation1(); } catch (SomeBusinessExeption ex) { status.setRollbackOnly(); } } });

프로그래밍 방식 VS 선언적 방식

트랜잭션 작업이 많지 않다면 프로그래밍 방식이 더 좋은 선택이 될 수 있습니다.

예를 들어, 몇 개의 Update가 전부인 웹 어플리케이션을 개발한다면 스프링이나 다른 기술을 사용한 트랜잭션 프록시 설정을 원치 않을 수도 있습니다. 이런 경우에는 TransactionTemplate는 좋은 처리 방식이 될 수 있습니다.

다른 예로, 수많은 트랜잭션 작업이 필요한 어플리케이션에서는 일반적으로 선언적 트랜잭션 관리가 좋습니다.

이 방식은 트랜잭션 관리를 비즈니스 로직과 분리하며, 설정하기 어렵지 않습니다. 그리고 비용적인 면에서도 유리하게 됩니다.

from http://minisiri.tistory.com/10 by ccl(A) rewrite - 2021-12-10 14:27:37