복붙노트

[SPRING] 스프링 빈에서는 트랜잭션을 사용할 수있는 시스템 종료 방법을 사용할 수 있습니까?

SPRING

스프링 빈에서는 트랜잭션을 사용할 수있는 시스템 종료 방법을 사용할 수 있습니까?

스프링 빈의 destroy 메소드에서 데이터베이스의 일부 내용을 정리하기 위해 쿼리를 실행하고 싶다. 봄은 내가 찾을 수있는 어떤 방법으로도 이것을 허용하지 않는 것처럼 보인다.

오류는 항상 다음과 같습니다.

다음은 bean이 더 이상 필요하지 않을 때 shutdownDestroy를 호출하는 스프링을 알려준다. 그러나 트랜잭션을 사용할 때 위의 오류가 발생합니다.

<bean id="someId" name="someName" class="someClass"
 destroy-method="shutdownDestroy"/>

공통 라이프 사이클 주석을 사용할 때도 마찬가지입니다.

<bean class="org.springframework. ... .CommonAnnotationBeanPostProcessor"/>

@PreDestroy로 메소드를 표시하십시오. 이 방법은 트랜잭션을 사용할 수도 없습니다.

이 작업을 수행 할 수있는 방법이 있습니까?

편집하다: 감사! 빈을 SmartLifecycle을 구현하고 다음을 추가하면 매우 잘 작동합니다.

private boolean isRunning = false;

@Override
public boolean isAutoStartup() {return true;}

@Override
public boolean isRunning() {return isRunning;}

/** Run as early as possible so the shutdown method can still use transactions. */
@Override
public int getPhase() {return Integer.MIN_VALUE;}

@Override
public void start() {isRunning = true;}

@Override
public void stop(Runnable callback) {
    shutdownDestroy();
    isRunning = false;
    callback.run();
}

@Override
public void stop() {
    shutdownDestroy();
    isRunning = false;
}

해결법

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

    1.재미있는 질문. bean이 SmartLifeCycle을 구현하게함으로써 그렇게 할 수 있어야한다고 말하고 싶다.

    재미있는 질문. bean이 SmartLifeCycle을 구현하게함으로써 그렇게 할 수 있어야한다고 말하고 싶다.

    그렇게하면 int getPhase (); 메서드는 Integer.MAX_VALUE를 반환하고, ApplicationContext가 마침내 종료 될 때 처음 호출됩니다.

    참고:

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

    2.나는이 같은 문제를 보게된다. 체크 봄의 소스 코드 후, U는 구현하려고 할 수 있습니다

    나는이 같은 문제를 보게된다. 체크 봄의 소스 코드 후, U는 구현하려고 할 수 있습니다

    public class SomeBean implements ApplicationListener<ContextClosedEvent> {
        public void onApplicationEvent(ContextClosedEvent event) {
            stopHook();
        }
    }
    

    onApplicationEvent는 bean destory 전에 호출 될 것이고, spring의 org.springframework.context.support.AbstractApplicationContext # doClose 메소드에서 확인할 수있다. 아래에 붙여 넣기 때문에 ContextEvent -> LifeCycle -> Bean destory.

            try {
                // Publish shutdown event.
                publishEvent(new ContextClosedEvent(this));
            }
            catch (Throwable ex) {
                logger.warn("Exception thrown from ApplicationListener handling ContextClosedEvent", ex);
            }
    
            // Stop all Lifecycle beans, to avoid delays during individual destruction.
            try {
                getLifecycleProcessor().onClose();
            }
            catch (Throwable ex) {
                logger.warn("Exception thrown from LifecycleProcessor on context close", ex);
            }
    
            // Destroy all cached singletons in the context's BeanFactory.
            destroyBeans();
    
            // Close the state of this context itself.
            closeBeanFactory();
    
            // Let subclasses do some final clean-up if they wish...
            onClose();
    
  3. from https://stackoverflow.com/questions/5891032/in-a-spring-bean-is-it-possible-to-have-a-shutdown-method-which-can-use-transact by cc-by-sa and MIT license