JAVA 정리노트

Spring, 중첩 트랜잭션(Nested Transaction)

Dodledd 2024. 10. 8. 17:13

트랜잭션(Transaction)

데이터베이스의 상태를 변화시키기 위한 일련의 작업을 하나로 묶은 논리적 단위입니다.

이 논리적 작업 단위는 모두 성공적으로 완료되거나,
하나라도 실패하면 전체 작업이 취소되도록 보장하는 것이 핵심입니다.

 

ACID 원칙

  1. Atomicity (원자성)
    •  트랜잭션은 하나의 단위로 실행되며, 모든 작업이 성공적으로 완료되거나 모두 실패하여 데이터베이스에 전혀 반영되지 않아야 합니다.
    •  예를 들어, 은행에서 A 계좌에서 B 계좌로 돈을 이체할 때, A 계좌에서 돈이 빠져나가고 B 계좌에 돈이 입금되는 작업이 하나의 트랜잭션으로 묶여야 합니다. 만약 중간에 오류가 발생하면, 모든 작업이 취소되어야 합니다.
  2. Consistency (일관성)
    •  트랜잭션이 성공적으로 완료된 후 데이터베이스는 항상 일관된 상태를 유지해야 합니다. 일관성 있는 상태란 데이터베이스에 저장된 데이터가 모든 제약 조건을 만족하는 상태입니다.
    •  예를 들어, 은행 계좌에 음수 잔고가 발생하지 않도록 하는 규칙이 있다면, 트랜잭션이 끝난 후에도 이 규칙이 유지되어야 합니다.
  3. Isolation (격리성)
    •  트랜잭션은 다른 트랜잭션과 독립적으로 실행되어야 하며, 동시에 여러 트랜잭션이 실행되더라도 서로 간섭하지 않아야 합니다.
    •  즉, 하나의 트랜잭션이 완료되기 전까지는 다른 트랜잭션이 그 트랜잭션이 수정 중인 데이터를 볼 수 없습니다. 이를 통해 다중 사용자가 동시에 데이터를 수정하는 상황에서도 데이터 무결성이 보장됩니다.
  4. Durability (지속성)
    • 트랜잭션이 성공적으로 완료되면, 그 결과는 영구적으로 데이터베이스에 저장되어야 하며, 시스템 장애가 발생하더라도 손실되지 않아야 합니다.
    • 예를 들어, 전원이 꺼지거나 시스템 오류가 발생하더라도, 완료된 트랜잭션의 결과는 데이터베이스에 그대로 남아 있어야 합니다.

트랜잭션의 생명주기

  1. BEGIN: 트랜잭션이 시작됩니다.
  2. COMMIT: 트랜잭션이 성공적으로 완료되었음을 데이터베이스에 알리고, 변경 사항을 영구적으로 저장합니다.
  3. ROLLBACK: 트랜잭션 중 오류가 발생하거나 취소 요청이 있으면, 트랜잭션 내에서 수행된 모든 작업을 취소하고 이전 상태로 되돌립니다.

Spring 에서는 어노테이션을 메서드나 클래스에 붙여서 적용시킵니다.

@Transactional
public void someMethod() {
    // 트랜잭션 내에서 실행될 코드
}

 

트랜잭션 전파(Propagation)

트랜잭션 전파는 트랜잭션이 이미 진행 중일 때 새로운 트랜잭션이 어떻게 동작할지를 정의합니다.

가장 큰 예로 중첩 트랜잭션이 있습니다.

 

중첩 트랜젝션을 설명하기전에 먼저 전파 옵션에 대해 알아보겠습니다.

 

주요 전파 옵션

  • REQUIRED: 기본 값으로, 기존 트랜잭션이 있으면 그 트랜잭션에 참여하고, 없으면 새로운 트랜잭션을 시작합니다.
  • REQUIRES_NEW: 항상 새로운 트랜잭션을 시작하고, 기존 트랜잭션이 있으면 이를 일시 중단합니다.
  • SUPPORTS: 트랜잭션이 있으면 그 트랜잭션에 참여하고, 없으면 트랜잭션 없이 실행됩니다.
  • MANDATORY: 이 전파 방식은 반드시 트랜잭션이 있어야만 동작합니다. 만약 트랜잭션이 없으면 예외가 발생합니다.
  • PROPAGATION_NEVER: 이 전파 방식은 트랜잭션이 존재하지 않을 때만 동작합니다. 만약 트랜잭션이 있으면 예외가 발생합니다.

outher

@Service
public class TransactionService {

    @Autowired
    private SubTransactionService subTransactionService;

    // 전파 옵션: REQUIRED
    @Transactional(propagation = Propagation.REQUIRED)
    public void outerTransaction() {
        System.out.println("Outer Transaction Start");
        // 데이터베이스에 어떤 작업 수행
        subTransactionService.innerTransaction(); // 내부 메서드 호출
        System.out.println("Outer Transaction End");
    }
}

 

inner

@Service
public class SubTransactionService {

    // 전파 옵션: REQUIRES_NEW
    @Transactional(propagation = Propagation.REQUIRES_NEW)
    public void innerTransaction() {
        System.out.println("Inner Transaction Start");
        // 데이터베이스에 어떤 작업 수행
        System.out.println("Inner Transaction End");
    }
}

 

 

 

 회사에서 자주 사용하는 전파옵션

  • NOT_SUPPORTS: 트랜잭션이 존재하면 그 트랜잭션을 일시 중단하고, 트랜잭션 없이 메서드를 실행합니다.
    즉, 위의 전파옵션은 항상 독립적으로 실행되고 상위 트렌젝션의 영향을 받지만 하위 트렌젝션에게 영향을 끼치지는 않습니다.

예시 : RbckbrkdService

//롤백처리관리자_재처리
@Transactional(propagation = Propagation.NOT_SUPPORTED)
public int rollBackProc_RE(MData param) throws MEPSException
{

}