본문 바로가기

개발/Spring Boot

스프링 @Transactional

배경


이전 글에서는 트랜잭션 격리 수준에 대해 이야기를 했었는데 이 번 글은  스프링의 @Transactional에 대해 알아보려고 합니다. 왜 쓰고 어떻게 동작하는 것일까요?

 

내용


[ Transaction ]

우리는 DB 데이터를 수정하고 조회하는 일을 빈번하게 하고 있습니다. 도중에 예외가 발생하게 되면 이전이 상태로 되돌아가야 하는데 이렇게 작업을 진행하다가 문제가 생겼을 경우 이전 상태로 롤백하기 위해 사용되는 것이 트랜잭션입니다. 또한 트랜잭션은 더이상 쪼갤 수 없는 최소 작업단위를 의미합니다. 보통 commit과 rollback으로 관리가 되어지죠. 이런 트랜잭션을 쓰는 가장 큰 이유 중 하나는 돈과 관련된 문제가 크기 때문입니다. 예를들어서 요즘 간편하게 app을 통해서 돈을 주고받는데 트랜잭션이 없다면 어떻게 될까요? 장애가 터지게 되면 돈이 증발해버리는 일이 빈번하게 발생할 수도 있겠죠.

 

[스프링의 @Transactional ]

기본적으로 DB는 자동 커밋(AUTO COMMIT)을 사용합니다. 하지만 하나의 작업이 여러개의 쿼리로 이루어지는 경우 자동 커밋을 사용하면 안되고 하나로 묶어서 관리하기 위해 트랜잭션을 사용합니다. 스프링의 @Transactional은 AOP(Aspect-Oriented Programming) 기반으로 트랜잭션을 적용할 수 있게 도와줍니다. 이를 붙이게 되면 spring에서 Connection을 가지고와서 자동 커밋을 비활성화 하고 트랜잭션을 시작하게 됩니다. 그리고 이 커넥션을 하나의 thread에서 공유할 수 있도록 thread local 변수에 저장하는 트랜잭션 동기화까지 진행해주죠.

 

[ AOP? ]

추가로 알아보자면 AOP기반의 객체들은 모두 proxy로 사용하게 된다는 점입니다. 왜 이렇게 사용하는 걸까요? 프록시 객체는 원래 객체를 감싸고 있는 객체로, 원래의 객체와 타입은 동일합니다.

 

우리가 만약 AOP를 사용하지 않게 된다면 어떻게 될까요? @Transactional을 예로 들자면 transaction 시작부터 transaction종료까지 하나의 메서드 내에서 하나하나 모두 작성해 주어야 합니다. 하지만 @Transactional을 사용하게 되면 transaction의 시작과 종료를 해당 메서드에서만 특정지어서 실행하게 할 수 있죠. Proxy로 생성된 객체를 보게 된다면, 아마 AOP의 @Before, @After 등을 활용해서 시작과 끝을 안전하게 보장해주는 코드가 들어있을 겁니다.

 

하지만 무조건 메서드 위에 @Transactional을 붙여서 사용하는게 좋은건 아닙니다. 사용할 범위를 잘 지정해주지 않으면, transaction 전파가 일어나면서 의도하지 않은 rollback이나 commit이 발생할 수 있습니다.

 

 

transaction 전파란 무엇일까요? 이는 다음 글에서 다뤄보도록 하겠습니다.

 

 

참고

https://mangkyu.tistory.com/312

 

[Spring] 예제 코드를 통해 스프링 @Transactional의 동작 방식에 대해 완벽하게 이해하기(parallelStream에

1. 스프링 @Transactional의 동작 방식에 대해 완벽하게 이해하기 [ parallelStream에서 @Transactional을 사용하는 예제 코드 ] 다음과 같은 간단한 JPA 엔티티가 있다. @Entity @Getter @NoArgsConstructor public class MyEnt

mangkyu.tistory.com

 

 

'개발 > Spring Boot' 카테고리의 다른 글

MapStruct의 이해  (2) 2025.01.03
트랜잭션 전파  (1) 2024.12.03