title: In a spring bean is it possible to have a shutdown method which can use transactions?
body: <p>In the destroy method of a spring bean I want to execute some queries to clean up some stuff in the database. Spring doesn't seem to allow this by any means I can find.</p>
  
  <p>The error is always something like:</p>
  
  <blockquote>
    <p>Invocation of destroy method failed on
    bean with name 'someBean':
    org.springframework.beans.factory.BeanCreationNotAllowedException:
    Error creating bean with name
    'transactionManager': Singleton bean
    creation not allowed while the
    singletons of this factory are in
    destruction (Do not request a bean
    from a BeanFactory in a destroy method
    implementation!)</p>
  </blockquote>
  
  <p>The following will tell spring to call shutdownDestroy after the bean is no longer needed. But, I get the above error when trying to use transactions.</p>
  
  <pre><code>&lt;bean id="someId" name="someName" class="someClass"
   destroy-method="shutdownDestroy"/&gt;
  </code></pre>
  
  <p>The same is true when I enable common lifecycle annotations using:</p>
  
  <pre><code>&lt;bean class="org.springframework. ... .CommonAnnotationBeanPostProcessor"/&gt;
  </code></pre>
  
  <p>and then mark the method with <code>@PreDestroy</code>. That method can't use transactions either.</p>
  
  <p>Is there any way to do this?</p>
  
  <p>EDIT:
  Thanks! I had the bean implement SmartLifecycle and adding the following and it works very nicely.</p>
  
  <pre><code>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;
  }
  </code></pre>