-
@Transactional이란 무엇인가Java 2023. 11. 22. 23:58
개요
친구가 문제를 줬다.
dao.saveMail(mailDto); 이후에 예외가 발생하면 어떻게 될까?
- 첨부파일은 이미 저장되어 있는데 삭제되어야 할까?
- DB에 보낸 메일정보를 저장은 삭제되어야 할까?검색해봤을 땐 스프링은 DB별로 에러코드를 정리해놔서 DB에서 생기는 에러코드를 통해 동적으로 예외를 전환해줄 수 있다는 것이다. 그래서 스프링이 제공하는 에러코드를 통해 동적으로 처리한다고 대답했지만,
@Transactional 어노테이션에 대해서 찾아보면 좋을 것 같다고 추천해줘서 정리를 하려한다
트랜잭션이란?
트랜잭션이란 데이터베이스 관리 시스템 또는 유사한 시스템에서 상호작용의 단위이다. 여기서 유사한 시스템이란 트랜잭션이 성공과 실패가 분명하고 상호 독립적이며, 일관되고 믿을 수 있는 시스템을 의미한다.
데이터의 정합성을 보장하기 위해 고안된 방법이다.트랜잭션의 특성(ACID)
이론적으로 데이터베이스 시스템은 각각의 트랜잭션에 대해 원자성(Atomicity), 일관성(Consistency), 독립성(Isolation), 영구성(Durability)을 보장한다. 이 성질을 첫글자를 따 ACID라고 한다.
- 원자성(Atomicity)
트랜잭션이 완전히 성공하거나 완전히 실패하는 단일 단위로 처리되도록 보장하는 능력으로
작업들이 부분적으로 실행되다가 중단되지 않는 것을 보장하는 능력이다. - 일관성(Consistency)
트랜잭션 처리 전과 처리 후 데이터 모순이 없는 상태를 유지하는 것을 의미한다 - 독립성(Isolation)
트랜잭션을 수행 시 다른 트랜잭션의 연산 작업이 끼어들지 못하도록 보장하는 것을 의미한다.
즉, 동시에 실행되는 트랜잭션들이 서로 영향을 미치지 않도록 격리한다. - 영구성(Durability)
성공적으로 수행된 트랜잭션은 영원히 반영(기록)되어야 함을 의미한다.
트랜잭션은 로그에 모든 것이 저장된 후에만 commit 상태로 간주될 수 있다.
즉, 트랜잭셔널 데이터베이스는 ACID에 맞게 특정 실행단위에서 오류가 발생하면 전체 실행 내용을 롤백해줘야 한다.
트랜잭셔널 데이터베이스 : 트랜잭션을 지원하는 데이터 베이스 관리 시스템
@Transactional
@Transactional 어노테이션을 클래스나 메서드에 붙여주는 것을 선언적 트랜잭션이라고 한다.
비즈니스 로직이 트랜잭션 처리가 필요한 경우, 트랜잭션 처리 코드와 비즈니스 로직이 같이 있다면 코드 중복과 가독성을 떨어뜨릴 수 있다.따라서 선언적 트랜잭션을 사용해서 트랜잭션 처리와 비즈니스 로직을 분리한다.
@Transactional 작동원리와 흐름
@Transaction어노테이션을 클래스 혹은 메서드에 붙여주면, Spring은 해당 메서드에 대한 프록시를 만들게 된다.
(코드를 감싸서 추가적인 연산을 수행하도록 하기 위해서)
트랜잭션의 시작과 연산 종료시의 커밋 과정이 필요하므로, 프록시를 생성해 해당 메서드의 앞뒤에 트랜잭션의 시작과 끝을 추가하는 것이다. 해당 로직은 AOP에 바탕을 두고 설계가 되었다.
스프링 컨테이너는 트랜잭션 범위의 영속성 컨텍스트 전략을 기본으로 사용한다.
서비스 클래스에서 @Transactional을 사용할 경우, 해당 코드 내의 메서드를 호출할 때 영속성 컨텍스트가 생긴다는 뜻이다. 영속성 컨텍스트는 트랜잭션 AOP가 트랜잭션을 시작할 때 생겨나고, 메서드가 종료되어 트랜잭션 AOP가 트랜잭션을 커밋할 경우 영속성 컨텍스트가 flush되면서 해당 내용이 반영된다. 이후 영속성 컨텍스트 역시 종료되는 것이다.
이러한 방식으로 영속성 컨텍스트를 관리해 주기 때문에, @Transactional을 쓸 경우 트랜잭션의 원칙을 정확히 지킬 수 있다.
프록시 : 프록시는 대리자 라는 뜻으로, 클라이언트가 사용하려고 하는 실제 대상인 것처럼 위장해서 클라이언트의 요청을 받아주는 역할을 한다.
프록시는 실제 대상인 것 처럼 위장함으로써 클라이언트는 구체 클래스를 알 필요가 없어진다.
프록시는 클라이언트의 요청을 받아서 원래 요청 대상에게 바로 넘겨주는게 아닌, 다양한 부가기능을 지원할 수 있다.
프록시 패턴
프록시 객체가 객체를 감싸서 클라이언트의 요청을 처리하는 패턴접근제어, 부가 기능 추가 등의 이유로 사용한다.
원래 객체와 같은 인터페이스를 구현해서 객체를 주입하고, 인터페이스의 메서드들을 위임받은 후 사용하고 코드를 추가한다.
그러나 프록시 패턴의 단점도 존재하는데, 이를 해결한 것이 Spring AOP이다. (이건 나중에 정리하도록 하자)
참고 자료
https://ko.wikipedia.org/wiki/ACID
https://kafcamus.tistory.com/30
https://velog.io/@betterfuture4/Spring-Transactional-%EC%B4%9D%EC%A0%95%EB%A6%AC
https://velog.io/@dltkdgus1850/Spring-%ED%94%84%EB%A1%9D%EC%8B%9C%EB%9E%80
'Java' 카테고리의 다른 글
@Bean과 @Component (1) 2023.11.24 객체지향 5원칙 SOLID (1) 2023.11.23 생성자 주입(Constructor Injection)을 권장하는 이유 (1) 2023.11.20 Early Return (0) 2023.11.18 JVM (0) 2023.11.16 - 원자성(Atomicity)