我有一个Web服务,该服务在初始化时使用数据源实例化一个QueryRunner。通过将它作为servlet上下文属性传递,它将一个QueryRunner对象用于来自Web应用程序使用的多个不同servlet的所有servlet请求。 IE。:

// in servlet context listener (on app initialization)
QueryRunner myQueryRunner = new QueryRunner(myDataSource);
myServletContext.setAttribute("queryRunner", myQueryRunner);

// in the servlets
QueryRunner myQueryRunner = (QueryRunner) myServletContext.getAttribute("queryRunner");
myQueryRunner.query(myStoredProcedure, handler, params)

我试图弄清楚这是否是瓶颈。小服务程序是否应在每个请求中实例化一个新的QueryRunner

当寻找答案时,我也发现了这个AsyncQueryRunner。但是我变得更加困惑,因为API文档中QueryRunnerAsyncQueryRunner的解释完全相同。

我浏览了here示例,似乎应该在每个请求中都将其实例化,但是我不确定这是否仅是示例代码。

换句话说,当使用DBUtils QueryRunner时,我应该:
  • 每个请求都使用一个QueryRunner实例吗? (我是什么
    现在执行)
  • 在每个servlet请求中实例化一个新的QueryRunner
  • 每个请求都使用一个AsyncQueryRunner实例吗?
  • 最佳答案

    QueryRunner是线程安全的类,因为它是无状态的,因此您可以在多线程环境中使用单个实例而不会出现任何问题。

    所有方法都是独立的,因此不需要同步方法访问,因此您也可以排除瓶颈。

    我在生产环境中使用它没有问题,但是我的实现遵循“用每个语句实例化一个新的QueryRunner”的模式,因为它是一个没有状态的委托(delegate)类,因此没有繁重的初始化并且没有堆消耗,并且我避免使用单例或其他共享实例存储此类的类。

    AsyncQueryRunner也是线程安全的,但其目的和用法完全不同(请参阅http://commons.apache.org/proper/commons-dbutils/examples.html)。它用于为长时间运行的语句创建非阻塞调用。如果您的业务层需要异步,这可能会很有用。

    综上所述:

  • 使用来自多个线程的单个QueryRunner实例(每个请求一个线程吗?)没有反指示,也没有优势,但是管理该实例的某个地方需要一些代码
  • 对每个线程甚至要通过其委派的每个语句使用新的QueryRunner实例,它具有两个主要优点:简单和本地化使用,并且如果不需要它们,则在内存中不存在任何实例。
  • AsyncQueryRunner需要对查询响应进行繁琐的管理,因此仅当您在业务代码中需要异步行为时才使用它。
  • 关于java - DBUtils QueryRunner实例化,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/14886606/

    10-10 09:27