Spring 트랜잭션 전파 및 격리

면책 조항 :이 문서는 블로거 원본입니다, 추적 에 의해-SA의 CC 4.0 저작권 계약, 복제, 원본 소스 링크이 문을 첨부 해주세요.
이 링크 : https://blog.csdn.net/neweastsun/article/details/102766906

Spring 트랜잭션 전파 및 격리

이 문서에서는 봄 @Transactional 및 절연 (절연) 및 전파 (전파) 특성을 제공하는 주석에 대해 설명합니다.

1. @Transactional 주석

@Transactional 어노테이션은 데이터베이스 트랜잭션의 작동 방법을 사용할 수 있습니다. 그리고 거래 관련 속성을 설정할 수 있습니다 : 속성 절연 (절연), 시간 제한 속성 (타임 아웃), 읽기 전용 속성 (읽기 전용) 및 롤백 조건, 트랜잭션 관리자를 지정할 수 있습니다.

1.1. 구현 세부 사항

Spring은 프록시 클래스를 생성하거나, 트랜잭션을 관리 커밋과 롤백하기 위해 만들어 바이트 코드를 조작 할 수 있습니다. 프록시 메서드 호출을 사용하여 봄 패션이 @Transactional 주석이 무시됩니다 경우에도 에이전트가 다른 클래스에서 호출 할 필요가 내부 문제를 무시됩니다.
예를 들어, 방법 callMethod 및 표시 @Transactional 주석, 봄 구현하는 과정에서 주변 트랜잭션 관리 코드의 일부를 패키지합니다 :

createTransactionIfNecessary();
try {
    callMethod();
    commitTransactionAfterReturning();
} catch (exception) {
    completeTransactionAfterThrowing();
    throw exception;
}

1.2. 주석을 사용 @Transactional

거래 노트는 클래스 나 메소드에 직접 인터페이스 할 수 있습니다. 인터페이스, 부모 클래스 인터페이스에있어서, 상위 클래스의 메소드, 클래스 방법 : 실제로는 로우에서 높은 우선 순위, 우선 순위에 의해 덮여있다.

클래스 레벨의 주석의 경우, 모든 public 메소드 표시되지 않은 사항에 봄 응용 프로그램 설정 노트, 개인, protecte 방법에 주석을 사용하는 경우, 봄은 무시됩니다.
예로서 다음 설명 :

@Transactional
public interface TransferService {
    void transfer(String user1, String user2, double val);
}

보통 우리는 인터페이스에서 트랜잭션을 설정하는 것이 좋습니다,하지만 봄 데이터 @Repository 상황에서 가능하지 않습니다. 인터페이스의 범위를 증가 또는 상위 클래스에 어디 주석이 제공됩니다 :

@Service
@Transactional
public class TransferServiceImpl implements TransferService {
    @Override
    public void transfer(String user1, String user2, double val) {
        // ...
    }
}

커버리지 주석 클래스 정의를 증가시키는 과정에서 경우 :

@Transactional
public void transfer(String user1, String user2, double val) {
    // ...
}

2. 트랜잭션 전달

트랜잭션 경계의 보급은 비즈니스 로직을 정의했다. 봄은 시작 또는 트랜잭션 설정의 전파를 중지 할 책임이있다.

봄 TransactionManager에 :: getTransaction 방법 취득을 호출하거나 전파 속성을 기반으로 트랜잭션을 생성합니다. 그것은 재산 TransactionManager를 만 전파 특성 TransactionManager에 특정 구현 지원의 일부의 모든 유형의 확산의 일부를 지원합니다. 다른 전파 특성의 상세한 설명.

2.1. 필수

필수 기본 속성입니다. 활성 트랜잭션에 대한 봄 체크 후 현재 활성 트랜잭션에 추가 된 새로운 트랜잭션 또는 비즈니스 로직을 작성하지 않은 경우 :

@Transactional(propagation = Propagation.REQUIRED)
public void requiredExample(String user) { 
    // ... 
}

기본 속성이 지정되지 않을 수 있습니다 :

@Transactional
public void requiredExample(String user) { 
    // ... 
}

다음 의사 코드에 대응 :

if (isExistingTransaction()) {
    if (isValidateExistingTransaction()) {
        validateExisitingAndThrowExceptionIfNotValid();
    }
    return existing;
}
return createNewTransaction();

2.2. SUPPORTS

속성을 지원, 봄 먼저 사용 반대로, 어떤 트랜잭션이 실행되지 않았다,이,이 활성 트랜잭션이 있는지 여부를 확인합니다.

@Transactional(propagation = Propagation.SUPPORTS)
public void supportsExample(String user) { 
    // ... 
}

의사 코드에 대응 :

if (isExistingTransaction()) {
    if (isValidateExistingTransaction()) {
        validateExisitingAndThrowExceptionIfNotValid();
    }
    return existing;
}
return emptyTransaction;

2.3. MANDATORY

속성이 의무적 속성으로 설정하면 액티브 한 트랜잭션 (transaction)가 있다면, 그것은 사용됩니다. 반대로 트랜잭션의 사용을 강제로 예외를 throw합니다.

@Transactional(propagation = Propagation.MANDATORY)
public void mandatoryExample(String user) { 
    // ... 
}

의사 코드에 대응 :

if (isExistingTransaction()) {
    if (isValidateExistingTransaction()) {
        validateExisitingAndThrowExceptionIfNotValid();
    }
    return existing;
}
throw IllegalTransactionStateException;

2.4.

결코 논리 속성 없습니다 : 액티브 한 트랜잭션 (transaction)가 예외를 던지고있는 경우.

@Transactional(propagation = Propagation.NEVER)
public void neverExample(String user) { 
    // ... 
}

의사 코드에 대응 :

if (isExistingTransaction()) {
    throw IllegalTransactionStateException;
}
return emptyTransaction;

2.5. NOT_SUPPORTED

활성 트랜잭션이 봄을 존재하는 경우 먼저 현재 트랜잭션을 중지하고 트랜잭션이없는 상태에서 비즈니스 로직을 실행합니다.

@Transactional(propagation = Propagation.NOT_SUPPORTED)
public void notSupportedExample(String user) { 
    // ... 
}

상자 정지 중 JtaTransactionManager를 지원 서비스를 제공합니다. 잡고 인용 거래를위한 다른 방법은, 다음 스레드 컨텍스트에서 중단을 시뮬레이션 제거합니다.

2.6. REQUIRES_NEW

액티브 한 트랜잭션 (transaction)가있는 경우 REQUIRES_NEW 재산, 봄이 현재 트랜잭션을 중단하고 새로운 사업을 만드는 것입니다.

@Transactional(propagation = Propagation.REQUIRES_NEW)
public void requiresNewExample(String user) { 
    // ... 
}

그리고 유사한 NOT_SUPPORTED, 우리는 JtaTransactionManager를 실제 거래 정지를 수행해야합니다.
의사 코드는 다음과 같이 :

if (isExistingTransaction()) {
    suspend(existing);
    try {
        return createNewTransaction();
    } catch (exception) {
        resumeAfterBeginException();
        throw exception;
    }
}
return createNewTransaction();

2.7. NESTED

포인트 저장이 표시된 경우 NESTED 속성에 대해 Spring은 트랜잭션을 확인합니다. 이는 후속 서비스 실행 예외가 발생하면 다시 저장 지점 롤 것을 의미한다. 그리고 필수는 활성 트랜잭션이없는 경우와 같은 속성.

DataSourceTransactionManager를이 속성을 지원, JtaTransactionManager를 구현의 일부도 지원할 수 있습니다. 속성이 점 저장 진실하고 nestedTransactionAllowed JDBC 드라이버 지원으로 설정되어있는 경우 JpaTransactionManager에만 JDBC 연결 지원 내부 클래스 특성, 다음 JPA 업무 JDBC 코드는 노력하고 있습니다. 다음과 같은 속성 설정 :

@Transactional(propagation = Propagation.NESTED)
public void nestedExample(String user) { 
    // ... 
}

3. 트랜잭션 격리

아이솔레이션 특성은 ACID (자성, 일관성, 격리 및 내구성)이 서로 분리 볼 동시 트랜잭션 애플리케이션을 변경하는 방법을 기술 중 하나이다. 각 트랜잭션 격리 수준은 0 개 이상의 동시 부작용을 방지하기 위해 :

  • 더러운 읽기 (더티 읽기) : 커밋되지 않은 동시 트랜잭션의 정보를 읽으십시오
  • 반복 불가능한 읽기 (반복 불가능한 읽기) : 동시 트랜잭션이 같은 라인과 노력을 갱신하는 경우, 반복적으로 다른 값을 얻기 위해 한 줄을 읽어
  • 매직 읽기 (팬텀 읽기) : 다른 트랜잭션 쿼리를 추가하거나 행을 삭제하고 제출하는 경우, 쿼리가 다른 레코드에 대한 값의 범위를 반환 반복

우리는 @Transactional 수 : 절연 격리 수준을 트랜잭션을 설정하여. DEFAULT, READ_UNCOMMITTED, READ_COMMITTED, REPEATABLE_READ, SERIALIZABLE : 봄은 오 개 열거 값을 제공합니다.

3.1. 기본 절연 특성

이 때문에 기본 RDBMS를 사용하여 새 봄 트랜잭션 격리 수준을 만들 때 데이터베이스의 변화에주의를 기울여야한다.
우리는 또한 속성 세트를 호출하는 다른 분리 방법을 사용하여 시나리오를 고려해야합니다, 정상적인 프로세스 격리는 새로운 트랜잭션이 생성 된 경우에만 적용. 따라서, 어떤 이유로, 격리에서 실행의 다른 방법을 원하지 않는다, 우리는 TransactionManager를가 :: setValidateExistingTransaction true로 설정해야합니다. 의사 코드는 다음과 같이 :

if (isolationLevel != ISOLATION_DEFAULT) {
    if (currentTransactionIsolationLevel() != isolationLevel) {
        throw IllegalTransactionStateException
    }
}

의 다른 격리 수준에서 살펴 보자.

3.2. READ_UNCOMMITTED

READ_UNCOMMITTED는 분리의 가장 낮은 수준, 동시 액세스를 허용 극대화입니다.
그것은 세 개의 동시성 부작용에 의해 영향을 받는다. 다른 동시 분리와 트랜잭션이 발생할 수있는 비 반복 읽기 팬텀 읽기 이외에, 커밋 트랜잭션 데이터를 읽는다. 따라서, 우리는 선을 다시 실행하거나 쿼리를 다시 읽기의 범위에서 다른 결과를 얻을 수 있습니다. 격리 수준 또는 클래스 메소드에 제공 될 수있다 :

@Transactional(isolation = Isolation.READ_UNCOMMITTED)
public void log(String message) {
    // ...
}

포스트 그레스 대신 READ_COMMITED를 사용, READ_UNCOMMITTED 절연 특성을 지원하지 않습니다. 오라클은 READ_UNCOMMITTED를 지원하지 않습니다.

3.3. READ_COMMITTED

READ_COMMITTED 더러운 방지 번째 단계 분리 다른 동시 부작용이 여전히 발생할 수 읽는다. 언 동시 트랜잭션이 영향 변화가 없지만 변화는 쿼리가 다시 변경됩니다 제출되었습니다.
코드의 절연을 설정 :

@Transactional(isolation = Isolation.READ_COMMITTED)
public void log(String message){
    // ...
}

READ_COMMITTED 포스트 그레스, SQL 서버와 오라클의 기본 수준.

3.4. REPEATABLE_READ

세 번째 분리 레벨은 REPEATABLE_READ 인 판독 및 반복 판독 오염 방지하고, 따라서 동시 트랜잭션이 커밋 변경 효과에 의해 영향을받지 않는다. 라인이 반복 될 때 쿼리는 다른 결과를 얻을 수 없습니다,하지만 몇 줄을 새 레코드를 얻거나 삭제할 수 있습니다.

두 개 이상의 동시 트랜잭션 읽고 같은 행 손실 업데이트를 발생을 업데이트 할 때이 레벨은 업데이트 손실을 방지 할 수 있습니다. REPEATABLE_READ 따라서 발생하지 않습니다 업데이트를 잃고, 동시 액세스 라인을 허용하지 않았다.

설정 코드 :

@Transactional(isolation = Isolation.REPEATABLE_READ) 
public void log(String message){
    // ...
}

REPEATABLE_READ의 MySQL의 기본 레벨은, 오라클은 REPEATABLE_READ를 지원하지 않습니다.

3.5. SERIALIZABLE

SERIALIZABLE 격리 수준은 최고입니다. 상기 모든 문제를 방지 할뿐만 아니라 때문에 위해 실행 동시 트랜잭션 최저 동시 액세스 효율을 야기 할 수있다. 즉, 실행 결과의 순서와 같은 동시 실행 SERIALIZABLE 트랜잭션 레벨의 세트이다. 설정 코드 :

@Transactional(isolation = Isolation.SERIALIZABLE)
public void log(String message){
    // ...
}

4. 요약

이 논문에서 우리는 전송 및 거래의 절연 특성 및 의미와 동시 트랜잭션의 서로 다른 특성의 영향에 대한 자세한 설명을 논의한다.

추천

출처blog.csdn.net/neweastsun/article/details/102766906