在Springbean中,是否可以有一个可以使用事务的关闭方法?

在Springbean中,是否可以有一个可以使用事务的关闭方法?,spring,shutdown,Spring,Shutdown,在Springbean的destroy方法中,我希望执行一些查询来清理数据库中的一些内容。春天似乎不允许我找到任何方法 错误总是类似于: 在上调用销毁方法失败 名为“someBean”的bean: org.springframework.beans.factory.beancreation不允许异常: 创建名为的bean时出错 “transactionManager”:单例bean 创建时不允许创建 这家工厂的单身汉都在工作 销毁(不请求bean) 以销毁方式从BeanFactory获取 实施!

在Springbean的destroy方法中,我希望执行一些查询来清理数据库中的一些内容。春天似乎不允许我找到任何方法

错误总是类似于:

在上调用销毁方法失败 名为“someBean”的bean: org.springframework.beans.factory.beancreation不允许异常: 创建名为的bean时出错 “transactionManager”:单例bean 创建时不允许创建 这家工厂的单身汉都在工作 销毁(不请求bean) 以销毁方式从BeanFactory获取 实施!)

下面将告诉spring在不再需要bean后调用shutdownDestroy。但是,我在尝试使用事务时遇到了上述错误

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

有趣的问题。我认为你应该可以在一天之内完成

这样,如果您的
intgetphase()
方法返回
整数.MAX_值
,当
应用程序上下文
最终关闭时,它将是第一个被调用的方法之一

参考资料:


    • 我遇到了同样的问题。检查spring的源代码后,您可以尝试实现

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

      我假设您的方法shutdownDestroy()具有@Transactional注释?您如何在该方法中执行查询?我正试图用一个由spring自动连接的EntityManager来实现这一点。自动连接工作正常,但当我尝试执行查询时,我得到了:javax.persistence.TransactionRequiredException:执行更新/删除查询实际上启动过程以
      Integer.MIN\u VALUE
      开始,以
      Integer.MAX\u VALUE
      结束,而关闭过程将应用相反的顺序,因此,如果希望在关机时首先执行方法,则应使用
      Integer.MAX\u VALUE
      而不是
      Integer.MIN\u VALUE
      。但是,在这种特殊情况下,任何值都允许从
      stop
      使用事务。
      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;
      }
      
      public class SomeBean implements ApplicationListener<ContextClosedEvent> {
          public void onApplicationEvent(ContextClosedEvent event) {
              stopHook();
          }
      }
      
              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();