JPA @Transactional

Cori1304·2025년 5월 12일
0

JAVA Spring 이론

목록 보기
5/8

@Transactional 개념

Spring이 제공하는 어노테이션으로, 메서드나 클래스에 선언하면 해당 범위 내의 메서드 실행 전후로 트랜잭션 처리 코드가 AOP를 통해 자동으로 적용됩니다. 이를 통해 트랜잭션의 시작, 커밋, 롤백 등의 처리가 명시적인 코드 없이도 수행됩니다.

트랜잭션(Transaction)이란

일반적인 Transaction 설명

⌜트랜잭션은 데이터베이스의 작업 단위로, 여러 작업을 하나로 묶어 모두 성공하거나, 모두 실패해야 하는 논리적 단위⌟

블로그 설명 Inpa Dev 👨‍💻:티스토리

⌜트랜잭션(Transaction)의 사전적 의미는 거래이고,
컴퓨터 과학 분야에서의 트랜잭션(Transaction)은 "더이상 분할이 불가능한 업무처리의 단위"를 의미한다. ⌟
⌜이것은 하나의 작업을 위해 더이상 분할될 수 없는 명령들의 모음, 즉, 한꺼번에 수행되어야 할 일련의 연산모음을 의미한다.⌟

내가 이해한 개념

DB와 어플리케이션의 데이터 거래(Transaction)에 있어서 안전성을 확보하기 위한 방법이 트랜잭션이다.

사용이유

1. 데이터 무결성을 보장하기 위해

이건 앞에 얘기한 트랜잭션에 대한 설명과 연관된다.

먼저 데이터 무결성(Data Integrity)이란, 데이터가 올바르고 일관된 상태로 유지되는 것을 의미한다. 즉, 예기치 않은 오류나 충돌로 인해 데이터가 잘못되거나 불일치되는 상황을 방지하는 것이다.

아래와 같은 예시가 데이터 무결성 또는 원자성을 만족하지 못하는 예로 아래와 같은 일이 일어나면 안되기에 transaction을 사용하고 JPA에서 @Transactional을 사용하는 이유이다.

ex) 은행 계좌 이체

은행 시스템에서 돈은 빠졌는데 입금은 안 됐다거나,

재고 관리에서 상품 수량은 줄었지만 주문 정보가 저장되지 않았다면

→ 이건 전형적인 무결성 위반

🧱 트랜잭션의 4대 특성 (ACID)

특성설명
A - Atomicity (원자성)작업이 전부 성공하거나 전부 실패해야 함
C - Consistency (일관성)작업 전후 DB의 상태는 일관돼야 함
I - Isolation (격리성)동시에 여러 트랜잭션이 실행되어도 서로 간섭 X
D - Durability (지속성)커밋된 데이터는 영구히 저장되어야 함

2. 지연 로딩 실패 방지

JPA에서 연관된 엔티티를 조회할 때, 지연 로딩(Lazy)을 설정할 경우 영속성 컨텍스트가 필요하다. 근데 영속성 컨텍스트는 트랙잭션 범위내에서 관리된다. 그렇기에 지연 로딩을 구현할때 @transactional이 필요하다.

지연 로딩이란?

지연로딩은 연관된 엔티티를 실제로 사용할 때까지 데이터베이스에서 로딩을 지연시키는 기법이다.

ex) 엔티티 A와 B가 일대다 관계를 가지고 있을 때, A 엔티티를 조회하더라도 B 엔티티를 바로 로딩하지 않고, 실제로 B엔티티의 내용이 필요한 시점에 해당 엔티티를 데이터베이스에 가져오는 방식입니다.

영속성 컨텍스트란?

영속성 컨텐스트란 엔티티를 영구 저장하는 환경이라는 뜻이다. 애플리케이션과 데이터베이스 사이에서 객체를 보관하는 가상의 데이터베이스 같은 역할을 한다. 엔티티 매니저를 통해 엔티티를 저장하거나 조회하면 엔티티 매니저는 영속성 컨텍스트에 엔티티를 보관하고 관리한다.

3. 코드 품질 개선

라이브러리와 프레임워크가 없어도 그 기능은 구현할 수 있다. 하지만 사용을 안하면 불편함 점이 존재하다. 보통은 개발에 편리성을 위해서 라이브러리와 프레임워크를 사용한다고 생각한다. @Transactional도 예외가 아니다. 아래 코드를 비교하면 코드 줄이 줄어들고 가독성이 향상되었고 다른 class에서 사용할 수 있는 재사용성이 또한 높은것이 사용 이유가 된다.

try-catch로 구현한 경우

@Autowired
private PlatformTransactionManager transactionManager;

@Autowired
private Buyer buyer

@Autowired
private Seller seller;

public void buy() {

  DefaultTransactionDefinition def = new DefaultTransactionDefinition();
  TransactionStatus status = transactionManager.getTransaction(def);

  try {
      buyer.send();			
      seller.receive();
      
      transactionManager.commit(status);

  } catch(Exception e) {

      transactionManager.rollback(status);

  } 
}

@Transactional 사용

@Autowired
private Buyer buyer

@Autowired
private Seller seller;

@Transactional
public void buy() {

  buyer.send();			
  seller.receive();

}

글을 쓰게된 배경

JPA를 적용한 개인 프로젝트를 진행 중, 간단한 CURD를 구현했다. MemberService를 만들고 test 코드도 만들었고 문제 없다고 종료,
그리고 오늘 구름딥 다이브 수업을 듣는데 Service 단에 @Transactional을 사용하는 코드를 보여준 강사님 !! 그걸보고 저는 🧐🤫 "어?... 나 사용 안 했네?? 문제 없나?"라는 생각이 들었다. 그렇기에 조사 시작

@Slf4j
@Service
@RequiredArgsConstructor
public class MemberService {
// 도메인 리포지토리 인터페이스 (그냥 repository 계층이라고 생각하면 됩니다. )
  private final Members members; 
  
  public boolean add(Member member) {
    try {
      members.save(member);

      return true;
    } catch (Exception e) {
      log.error("Failed to save member: " + e.getMessage());
      return false;
    }
  }

  public List<Member> getAllMembers() {
    return members.findAll();
  }

  public Map<String, List<String>> getMemberNamesGroupedByTeam() {
    Map<String, List<String>> result = new HashMap<>();
    List<Member> allMembers = getAllMembers();

    for (Member member : allMembers) {
      result.computeIfAbsent(member.getSmallGroup().getName(), k -> new ArrayList<>())
          .add(member.getName());
    }

    return result;
  }


  public Member getByName(String name) {
    return members.findByName(name);
  }


  public boolean updateInfo(Member member) {
    try {
      members.updateInfo(member);
      return true;

    } catch (Exception e) {
      log.error("Failed to update member: " + e.getMessage());
      return false;

    }
  }

}

개인 @Transactional 사용 안 했는데 문제 없나?

JPA에 구현체인 SimpleJpaRepository에는 이미 @Transactiona이 사용되고 있기에 정의가 필요한 메서드가 아니라면 Service에 @Transactional을 사용안해도 괜찮다 또한 Service에 @Transactional을 사용해도 큰 문제가 되지 않는다.

참고 자료

profile
개발 공부 기록

0개의 댓글