使用连接池的示例

消息驱动的 bean 侦听器端口组件以及执行出站消息传递的应用程序使用 JMS 连接池。

图 1 显示了 WebSphere® Application Server V7.5 和 V8.0的连接池工作方式。
图 1。 WebSphere Application Server V7.5 和 V8.0 -连接池的工作方式
显示如何在 WebSphere Application Server V7.5 和 V8.0中使用连接池属性的流程图。
图 2 显示了 WebSphere Application Server V8.5的连接池工作方式。
图 2。 WebSphere Application Server V8.5 -连接池的工作方式
显示如何在 WebSphere Application Server V8.5中使用连接池属性的流程图。

MDB 侦听器端口如何使用连接池

假定您在 WebSphere Application Server Network Deployment 系统上部署了 MDB ,即使用 IBM® MQ 作为 JMS 提供程序。 该 MDB 是针对使用某个连接工厂(例如名为 jms/CF1)的侦听器端口进行部署,并且最大连接数属性设置为 2,这意味着任一时间只能使用该工厂创建两个连接。

当侦听器端口启动时,该端口尝试使用jms/CF1 连接工厂创建与 IBM MQ的连接。

要执行此操作,该端口需要从连接管理器处请求连接。 由于这是第一次使用 jms/CF1 连接工厂,所以 jms/CF1 空闲连接池中没有连接,于是,连接管理器将创建新连接(例如名为 c1)。 请注意,此连接在侦听器端口的整个生命周期中始终存在。

现在,请考虑使用 WebSphere Application Server 管理控制台停止侦听器端口的情况。 在此情况下,连接管理器将获取该连接并将其放回到空闲池中。 但是,与 IBM MQ 的连接仍处于打开状态。

如果重新启动侦听器端口,该端口会再次要求连接管理器提供与队列管理器的连接。 由于空闲池中现在已有一个连接 (c1),因此连接管理器将从池中取出此连接,使其可供侦听器端口使用。

现在,假设您在应用程序服务器中部署了第二个 MDB,并且它使用不同的侦听器端口。

再假设您尝试启动第三个侦听器端口,该端口也配置为使用 jms/CF1 连接工厂。 这第三个侦听器端口从连接管理器处请求连接,然后连接管理器会查看 jms/CF1 的空闲池,发现该池为空。 随后它检查使用 jms/CF1 工厂创建的连接数。

由于 jms/CF1 的“最大连接数”属性设置为 2,并且您已使用该工厂创建了两个连接,因此连接管理器将等待 180 秒(这是连接超时属性的缺省值),以等待有连接变为可用。

但是,如果您停止了第一个侦听器端口,那么其连接 c1 将被放入 jms/CF1 的空闲池中。 连接管理器会检索此连接并将其分配给第三个侦听器。

如果现在尝试重新启动第一个侦听器,那么该侦听器必须等待另外两个侦听器端口中的某一个停止,然后第一个侦听器才能重新启动。 如果正在运行的侦听器端口在 180 秒内均未停止,那么第一个侦听器会收到 ConnectionWaitTimeoutException 错误并停止。

用于执行出站消息传递的应用程序如何使用连接池

对于此选项,假设应用程序服务器中只安装了一个 EJB(例如名为 EJB1)。 该 bean 通过以下方法实现了名为 sendMessage() 的方法:
  • 使用 connectionFactory.createConnection()从工厂 jms/CF1创建到 IBM MQJMS 连接。
  • 从连接创建 JMS 会话。
  • 从该会话创建消息生产者。
  • 发送消息。
  • 关闭生产者。
  • 关闭会话。
  • 调用 connection.close() 以关闭连接。

假设工厂 jms/CF1 的空闲池为空。 首次调用 EJB 时, Bean 尝试从工厂 jms/CF1创建到 IBM MQ 的连接。 由于该工厂的空闲池为空,因此连接管理器会创建新连接并将其分配给 EJB1。

该方法恰好在退出之前调用 connection.close()。 连接管理器不会关闭 c1,而是获取该连接并将其放入 jms/CF1 的空闲池中。

下次调用 sendMessage() 时, connectionFactory.createConnection() 方法会将 c1 返回到应用程序。

假设在第一个实例运行的同时还有第二个 EJB 实例也在运行。 当这两个实例均调用 sendMessage() 时,会使用 jms/CF1 连接工厂创建两个连接。

现在假设创建了该 bean 的第三个实例。 当第三个 bean 调用 sendMessage() 时,该方法会调用 connectionFactory.createConnection() 以使用 jms/CF1 创建连接。

但是,当前已使用 jms/CF1 创建了两个连接,此数目已达到此工厂的最大连接数。 因此,createConnection() 方法将等待 180 秒(这是连接超时属性的缺省值),以等待有连接变为可用。

但是,如果第一个 EJB 的 sendMessage() 方法调用 connection.close() 并退出,那么它之前使用的连接 c1 将被放回到空闲连接池中。 连接管理器将从空闲池中取回该连接并将其分配给第三个 EJB。 然后将返回该 bean 对 connectionFactory.createConnection() 的调用,从而允许完成 sendMessage() 方法。

使用相同连接池的 MDB 侦听器端口和 EJB

上述两个示例显示了侦听器端口和 EJB 如何独立使用连接池。 但是,您可以在同一应用程序服务器中同时运行侦听器端口和 EJB ,并使用同一连接工厂创建 JMS 连接。

您需要考虑此情况的影响

需要记住的关键一点是连接工厂由侦听器端口和 EJB 共享。

例如,假设您的侦听器和 EJB 同时运行。 这二者均使用 jms/CF1 连接工厂,这意味着已达到该工厂的“最大连接数”属性指定的连接限制。

无论是尝试启动另一个侦听器端口还是 EJB 的另一个实例,都必须等待连接返回到 jms/CF1 的空闲连接池。