복붙노트

[SPRING] Spring @ Transactional Annotation : 자체 호출

SPRING

Spring @ Transactional Annotation : 자체 호출

거래 방식이 트랜잭션 내에서 실행되지 않는 동일한 클래스 내부에서 호출되는 경우를 알고 있습니다. Spring은 트랜잭션 메소드에 대한 프록시를 생성하고 try-catch 블록에 래핑하고 예외가 발생하면 롤백합니다. 다음 시나리오를 고려하십시오.

@Transactional
public void saveAB(A a, B b)
{
    saveA(a);
    saveB(b);
}

@Transactional
public void saveA(A a)
{
    dao.saveA(a);
}

@Transactional
public void saveB(B b)
{
    dao.saveB(b);
}

다른 오브젝트에서 saveAB이 호출되고 saveB에서 예외가 발생했다고 가정하면 saveA는 성공적으로 완료되었지만 saveB는 완료되지 않았습니다. 내 지식으로는 saveA와 saveB가 (같은 객체에서 호출되었으므로) 트랜잭션이 아니더라도 saveAB는 트랜잭션이므로 롤백해야합니다.

내가 왜 이해하지 못하는 이유는 사람들이 자기 호출이 트랜잭션을 중단시키는 이유는 무엇입니까? 호출자 메서드가 트랜잭션이면 모든 것이 예상대로 작동하지 않아야합니다. 내가 여기서 누락 된 것이 있습니까?

해결법

  1. ==============================

    1.나는 자기 호출이 거래를 중단한다는 말을 들어 본 적이 없다. 내가 아는 한 자체 호출은 새로운 트랜잭션을 시작하지 않으며 이미 이유를 언급 한 것입니다.

    나는 자기 호출이 거래를 중단한다는 말을 들어 본 적이 없다. 내가 아는 한 자체 호출은 새로운 트랜잭션을 시작하지 않으며 이미 이유를 언급 한 것입니다.

    Spring의 트랜잭션 관리 사양에서 발췌

    saveAB ()에서 @Transaction 주석을 제거하면 saveA () 및 saveB () 메소드가 @Transactional 주석을 달았음에도 트랜잭션에서 실행되지 않는다는 것을 알 수 있습니다. 그러나 클래스 외부에서 saveA () 또는 saveB ()를 호출하면 예상대로 트랜잭션에서 실행됩니다. 그것이 사람들의 충고가 자기 부름에 신중해야하는 이유입니다.

    public void saveAB(A a, B b)
    {
        saveA(a);
        saveB(b);
    }
    
    @Transactional
    public void saveA(A a)
    {
        dao.saveA(a);
    }
    
    @Transactional
    public void saveB(B b)
    {
        dao.saveB(b);
    }
    

    필자의 견해에 따르면, 공개 메서드를 자체 호출하는 것은 나쁜 생각입니다.

  2. ==============================

    2.saveAB를 저장할 수 있고 saveB가 예외를 throw하면 트랜잭션이 롤백됩니다.

    saveAB를 저장할 수 있고 saveB가 예외를 throw하면 트랜잭션이 롤백됩니다.

    save가 @Transactional로 주석을 달지 않으면 자체 호출은 초국적 인 행동을 저해 할 것이다.

    그래서 당신은 당신의 모범에서 무엇이든 놓치지 않았습니다.

  3. from https://stackoverflow.com/questions/23931698/spring-transactional-annotation-self-invocation by cc-by-sa and MIT license