一尘不染

如何取消正在运行的SQL查询?

hibernate

我知道statement.cancel()可用于取消正在运行的SQL查询,但是我想知道的是,我将如何在另一个线程中保持该语句对象。

用例:

  • 我请求启动一个运行语句的线程。
  • 然后从一个单独的请求(另一个线程),我可能想取消此线程。

我将如何在这个 新请求中 获得声明以在其中调用cancel方法。

在某些情况下,我可能要运行多个语句。

附加信息,它是一个Web应用程序,使用spring框架,hibernate和JPA。现在,UI中有2个按钮,按钮1将触发SQL查询,按钮2必须取消该查询

我提到了这个示例,但是它使用相同的线程来调用新线程,而我不能这样做。

这是启动查询的方式:

    Query query = mEntityManager.createNativeQuery(globalQuery.toString());
    List<Object[]> results = query.getResultList();

编辑:

  1. 我能想到的一种方法是跟踪所有正在运行的语句,然后找到必须取消SQL语句的语句。

阅读 1409

收藏
2020-06-20

共1个答案

一尘不染

有两个不同的会话可以为您提供帮助:

如果您想在同一个用户的两个请求之间交换一个类似于您的语句的对象,而这些请求是并行运行还是一个接一个地运行,则通常将它们存储在HttpSessionHttpServletRequest

您可以使用SessionHibernate取消当前查询:

public void startLongRunningStatement() {
  EntityManager entityManager = ...

  // Aquire session
  Session hibernateSession = ((HibernateEntityManager) em.getDelegate()).getSession();

  // Store the HibernateSession in the HttpSession
  HttpSession httpSession = servletRequest.getSession()
  httpSession.setAttribute("hibernateSession", hibernateSession);

  try {
    // Run your query  
    Query query = mEntityManager.createNativeQuery(globalQuery.toString());
    List<?> results = query.getResultList();

  } finally {
    // Clear the session object, if it is still ours
    if (httpSession.getAttribute("hibernateSession") == hibernateSession) {
      httpSession.removeAttribute("hibernateSession");
    }
  }
}

public void cancel() {
  // Get the Hibernate session from the HTTP session
  HttpSession httpSession = servletRequest.getSession()
  Session hibernateSession = (Session) httpSession.getAttribute("hibernateSession");
  if (hibernateSession != null) {
    // Cancel the previous query
    hibernateSession.cancelQuery();
  }

}
2020-06-20