对企业">信息系统 (EIS) 的关系和过程访问的连接管理架构都基于 Java EE Connector Architecture (JCA) 规范。Connection Manager (CM) 将一个应用服务器中的连接加入池中进行管理,既能够管理通过 JCA 规范定义的资源适配器所获取的连接,也能够管理通过 Java 数据库连接 (JDBC) 规范定义的数据源所获取的连接。IBM WebSphere Application Server 支持管理员建立后端连接池,以便在一个应用服务器上共享应用程序。因为避免了为每个访问后端资源的新请求创建新连接的开销,连接池可改善应用程序的响应时间。
最优的连接使用
通常,应用程序组件在 JNDI(Java Naming and Directory Interface,Java 命名和目录接口)名称空间中查找连接工厂,然后使用该连接工厂获取与底层 EIS 的连接。小心使用这些连接可避免连接被耗尽,还可以帮助应用程序进行扩展。
以下是为了实现最优的连接使用而必须采取的预防措施:
立即显式关闭连接
应用程序组件在连接工厂上调用 getConnection 方法来获取 EIS 连接。返回的连接实例表示一个底层物理连接的一个应用程序级句柄。在应用程序组件完成该连接的使用后,应该使用连接接口上的关闭方法关闭连接。如果应用程序组件没有在使用后关闭分配的连接,该连接只能在以后清理事务时由应用服务器关闭。这会拒绝其他对使用该连接的请求,限制了可伸缩性。
建议在连接句柄已被使用且不再需要时,应用程序组件显式关闭该句柄。这会减少连接泄漏的可能性,增强应用服务器将与 EIS 的物理连接加入池中的能力。
共享的连接和 LocalTransactionContainment
WebSphere Application Server 中的连接默认情况下是共享的。使用一个可共享的连接意味着,如果条件允许,应用程序的不同 getConnection() 请求实际上会收到采用与该资源相同的物理连接进行连接的句柄。对于共享连接,共享范围是事务。在全局事务外操作的应用程序需要使用 WebSphere Application Server 中的一个称为 LocalTransactionContainment(LTC) 的默认上下文。
只有在 LocalTransactionContainment 结束后,共享连接才能用于来自其他事务的请求。所以不使用长期运行且嵌套的 LocalTranactionContainment 始终是明智之举,这些 LocalTranactionContainment 会长期持有共享连接并导致连接池耗尽。
应用程序组件可使用 JTA UserTransaction 接口或特定于一个 EIS 的事务分工 API,控制事务边界和避免长期运行的 LTC。
长期运行的查询
缓慢运行的查询将有一个数据库连接,而且该连接无法用于任何尝试访问相同资源的新请求。一个连接在任何时刻都只能处理一个操作;例如,如果一个查询用时 10 秒,那么另一个针对相同资源的请求将被阻止利用该连接。此外,缓慢运行的查询与更高的工作负载相结合,最终会导致连接池被耗尽。通过在 Performance Monitoring Infrastructure 中启用连接池统计信息,持续监视 UseTime 和其他统计信息,可能会提供帮助。
非共享连接
对标记为不可共享的资源的访问,意味着一个组件使用的连接句柄与该句柄所关联的物理连接之间具有一对一的关系。这种访问暗示着,每次对 getConnection 方法的调用仅向请求用户返回一个连接句柄。通常,如果您对连接执行的操作可能导致共享该连接的另一个应用程序中发生意外的行为,那么您必须选择不可共享。
选择非共享连接可能会增加使用的连接数量,导致在更高的负载上耗尽连接池,因为将为每个请求都使用了一个新连接。
AutoCommit 和 LocalTransactionContainment
当一个连接处于自动提交模式时,该连接上的操作会在被执行后自动提交。如果必须将多次交互分组到单个事务中(无论是本地还是 XA)并作为一个单元来提交或回滚,自动提交模式将会关闭。
对于在一个事务外使用的连接,应将自动提交模式设置为 true,LocalTransactionContainment 将被激活。使用非共享连接时,如果应用程序将 Autocommit 设置为 false,那么该连接无法用于其他请求,甚至在应用程序关闭了该连接时也是如此。在关闭一个连接之前,应用程序必须在该连接对象上显式调用提交方法。
事务隔离和只读属性
如果一个应用程序更改了事务隔离级别或只读属性,系统会为该应用程序提供一个新连接,而不是提供相同的共享连接,甚至在同一个事务中也是如此。如果从应用程序中对事务隔离级别的频繁更改,将会得到不同的连接并增加需要的连接数量,最终导致连接池耗尽。
主体
同一个主体表示关系数据库需要使用同一个用户和密码。如果应用程序使用不同的用户 ID 和密码来获取连接,getConnection 调用返回的物理连接将会不同。当应用程序的资源身份验证设置被设置为 Application 时,您可以使用 getConnection() 或 getConnection(String userid, String password) 来获取连接。从这两个调用获取的连接不是共享的,即使与数据库关联的组件管理的身份验证别名拥有 getConnection(String userid, String password) 中使用的相同的用户 ID 和密码。
不可共享的 JMS 会话
JMS 提供程序的 JMS 连接是不可共享的,因为它们是非事务性的,Java EE Connector Architecture (JCA) 规范仅允许共享事务性资源。如果 JMS 资源引用中的 res-sharing-scope 被设置为 shareable,该设置将被忽略,并会使用不可共享的连接。但是,JMS 会话是事务性的,而且是可共享的。JMS 事务默认情况下是可共享的。
当一个可共享的 JMS 会话加入事务中时,关闭该会话不会向池中释放它。但是,关闭该连接会使该连接可用于其他应用程序。接下来,当同一个应用程序请求一个连接时,它可能在一些实例中获得一个新连接,在这些场景中,在应用程序创建一个会话时,将会创建一个新会话。
在这些场景中,要在会话关闭后尽快将它释放到池中,也可以将会话设置为不可共享。这意味着只要一个应用程序调用 Session.close(),就会自动从关联的任何事务释放 JMS 会话并返回到会话池。在将会话设置为不可共享之前,需要适当地确认上述场景并了解其他影响。
结束语
在以最佳方式使用加入池中的连接方面,应用程序对 JCA 连接的使用具有非常重要的作用。遵循一些使用模式并拥有连接行为的知识,这些可以帮助您避免耗尽连接池和帮助提高可伸缩性。