복붙노트

[SPRING] 정적 메소드와의 트랜잭션

SPRING

정적 메소드와의 트랜잭션

스프링 프로젝트에서 트랜잭션을 관리하기 위해 정적 메소드에 @Transactional을 사용하는 이유는 무엇입니까?

@Transactional은 비 정적 메소드에서는 잘 작동하지만 정적 메소드에서는 잘 작동하지 않습니다.

해결법

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

    1.왜 제안하고있는 것과 같은 것이 작동하지 않는지를 이해하기 위해서는 @Transactional을 사용하는 빈을 Spring이 어떻게 처리 하는지를 먼저 높은 수준에서 이해해야 만합니다.

    왜 제안하고있는 것과 같은 것이 작동하지 않는지를 이해하기 위해서는 @Transactional을 사용하는 빈을 Spring이 어떻게 처리 하는지를 먼저 높은 수준에서 이해해야 만합니다.

    메소드 나 클래스를 @Transactional으로 주석하고 Spring Bean으로 만들 때 Spring은 해당 클래스에 대한 프록시를 효과적으로 생성합니다 (JDK 동적 프록시 또는 CGLIB 프록시 사용). 즉, 클래스가 사용될 때마다 (즉, Spring 관리 코드에서 가져온 것) 즉시 호출되는 코드는 아니지만 먼저 필요한 것이 무엇이든지간에 프록시가 호출되고 코드가 호출됩니다 (캐싱을 지원하는 경우 코드는 전혀 호출되지 않습니다). 여기에서 기억해야 할 핵심 사항은 호출 코드 (사용자가 호출하는 경우 호출 사이트)가 전혀 변경되지 않고 필요한 대상 메소드 (프록시 메소드) 호출이 동일한 바이트 코드를 사용하는 JVM에 의해 수행된다는 것입니다 (invokevirtual 또는 invoke 인터페이스).

    이를 염두에두고 정적이 지원되지 않는 이유는 분명합니다. 정적 메서드에 대한 프록시를 만들 수 없습니다! 물론 Java Dynamic Proxy는이를 수행 할 수 없으며 CGLIB도 사용할 수 없습니다.

    이러한 기능을 지원하려면 호출하는 코드의 바이트 코드를 변경해야합니다. 정적 메서드 호출은 대상 메서드를 하드 코딩하는 바이트 코드의 invokestatic을 통해 구현되기 때문입니다.

    Spring 문서의이 부분은 Spring AOP에 대해 자세히 설명합니다.

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

    2.AspectJ를 사용한다면 간단하지만 추악한 해결 방법이있다.

    AspectJ를 사용한다면 간단하지만 추악한 해결 방법이있다.

    public static void doWhatever(final String param) {
        new Runnable() {
            @Transactional
            public void run() {
                // do whatever in transaction...
            }
        }.run();
    }
    
  3. ==============================

    3.이것은 다음을 사용하여 가능합니다.

    이것은 다음을 사용하여 가능합니다.

    NB :이 게시물에서는 패키지 전용 메서드 @Transactional을 만드는 방법에 대해 질문했습니다.

  4. from https://stackoverflow.com/questions/23569732/transactional-with-static-method by cc-by-sa and MIT license