"일꾼이 일을 잘하려면 먼저 도구를 갈고 닦아야 한다." - 공자, 『논어』.
첫 장 > 프로그램 작성 > @Transactional에서 기본 격리 및 전파 매개변수를 조정해야 하는 시기와 이유는 무엇입니까?

@Transactional에서 기본 격리 및 전파 매개변수를 조정해야 하는 시기와 이유는 무엇입니까?

2024-11-06에 게시됨
검색:862

When and Why Should You Adjust the Default Isolation and Propagation Parameters in @Transactional?

@Transactional의 격리 및 전파 매개변수

Spring의 @Transactional 주석에서 두 가지 중요한 매개변수는 데이터베이스 트랜잭션의 동작, 즉 격리와 전파를 정의합니다. . 이 문서에서는 기본값 조정을 고려해야 하는 시기와 이유를 살펴봅니다.

전파

전파는 트랜잭션이 서로 관련되는 방식을 정의합니다. 일반적인 옵션은 다음과 같습니다:

  • 필수: 기존 거래 내에서 코드를 실행하거나 코드가 없는 경우 새 코드를 생성합니다.
  • REQUIRES_NEW: 항상 새 트랜잭션을 생성하고 기존 트랜잭션을 일시 중지합니다.

기본값: 필수

격리

격리는 트랜잭션 간의 데이터 계약을 정의합니다. 다른 트랜잭션으로 인해 발생한 데이터 변경 사항에 대한 가시성 수준을 지정하여 특정 데이터 불일치를 방지합니다. 주요 격리 수준은 다음과 같습니다.

  • READ_UNCOMMITTED: 더티 읽기에 대한 보호가 없습니다.
  • SERIALIZABLE: 가장 강력한 격리로 데이터 충돌이 발생하지 않습니다.

기본값: 데이터베이스에 따라 다릅니다(예: MariaDB의 경우 REPEATABLE_READ)

실제 사례

트랜잭션이 다른 트랜잭션에 의해 이루어진 커밋되지 않은 변경 사항을 읽을 수 있는 더티 읽기(dirty read) 문제를 고려하십시오.

                                       Thread 1          Thread 2
                                               |              |
                                             Write(x)           |
                                               |              |
                                               |             Read(x)
                                               |              |
                                             Rollback           |
                                                 |             |
                                                   Value (x) is now dirty (incorrect)

이 시나리오에서 더티 읽기를 방지하려면 격리 수준을 READ_COMMITTED로 설정하고 전파 수준을 REQUIRED. 이 조합은 트랜잭션이 다른 트랜잭션에 의해 커밋된 데이터만 읽도록 보장합니다.

트랜잭션 사용자 정의

다음 예에서 provideService 메소드 항상 새 트랜잭션 내에서 실행되어 다른 동시 작업으로 인한 변경 사항이 실행을 방해하지 않도록 합니다.

@Transactional(propagation=Propagation.REQUIRES_NEW)
public void provideService() {
    repo1.retrieveFoo();
    repo2.retrieveFoo();
}

트랜잭션 동작 테스트

다양한 전파 수준의 동작을 확인하려면 Java 테스트를 사용할 수 있습니다.

@Test
public void testProvideService() {
    TransactionStatus status = transactionManager.getTransaction(new DefaultTransactionDefinition());
    fooService.provideService();
    transactionManager.rollback(status);
    // Assert repository values are unchanged ...
}

REQUIRES_NEW를 사용하면 fooService.provideService()는 별도의 트랜잭션 내에서 작동하므로 롤백되지 않습니다. 필수를 사용하면 모든 것이 롤백됩니다.

최신 튜토리얼 더>

부인 성명: 제공된 모든 리소스는 부분적으로 인터넷에서 가져온 것입니다. 귀하의 저작권이나 기타 권리 및 이익이 침해된 경우 자세한 이유를 설명하고 저작권 또는 권리 및 이익에 대한 증거를 제공한 후 이메일([email protected])로 보내주십시오. 최대한 빨리 처리해 드리겠습니다.

Copyright© 2022 湘ICP备2022001581号-3