不可共享和可共享连接
应用程序服务器支持不可共享和可共享的连接。应用程序中其他组件不能共享不可共享连接。使用此连接的组件全权控制此连接。
访问标记为不可共享的资源意味着组件使用的连接句柄和该句柄所关联的物理连接之间存在着一对一的关系。此访问意味着对 getConnection 方法的每次调用仅为请求用户返回连接句柄。通常,如果您对连接执行的操作可能导致另一个共享此连接的应用程序发生意外的行为(例如,意外地更改隔离级别),那么您必须选择“不可共享”。
将资源标记为“可共享”就能有更大的可伸缩性。只要每个 getConnection 请求都具有相同的连接属性,就能通过多个连接句柄共享物理连接(即,受管连接),而不必每次调用 getConnection() 时都从连接池中检索新的物理连接。但是,共享连接意味着任何用户都不能对连接执行可能更改其行为及破坏共享合作伙伴的任何操作(例如,更改隔离级别)。由于是由运行时来决定是否共享特定的连接,因此用户也不能编写假定进行共享的应用程序的代码。
连接属性要求
- Java™ 命名和目录接口 (JNDI) 名称。实际上它不是连接属性,此要求仅表示您只能共享同一服务器中相同数据源的连接。
- 资源认证
- 关系数据库中:
- 隔离级别(符合应用于 CMP Bean 的访问意向策略)
- 只读
- 目录
- 类型映射
有关与 CMP Bean 共享连接的更多信息,请参阅“与 CMP Bean 共享连接”主题。
- JNDI 名称。实际上它不是连接属性,此要求仅表示您只能共享同一服务器中相同连接工厂的连接。
- 资源认证
无法共享 IBM MQ JMS 提供程序的 JMS 连接,因为它们为非事务性 JMS 连接,而 Java™ EE 连接器体系结构 (JCA) 规范只允许共享事务性资源。如果在 JMS 资源引用中将 res-sharing-scope 设置为可共享,那么将忽略此设置,将使用不可共享的连接。但是,MQ 的 JMS 会话是事务性的,可以共享。缺省情况下,JMS 会话可共享,APAR PK59605 能够指定不可共享的会话。
缺省消息传递提供程序的 JMS 连接不同。借助缺省消息传递提供程序,可以共享连接。另一方面,会话不是由连接池管理,因此,无法共享或者不可共享。
与 CMP Bean 共享连接
- 在 CMP Bean 或方法之间共享连接
当所有 CMP Bean 方法都使用同一访问意向时,它们都共享同一物理连接。不同的访问意向策略将触发不同的物理连接分配。例如,CMP Bean 有两个方法;第一个方法与 wsPessimisticUpdate 意向相关联,而第二个具有 wsOptimisticUpdate 访问意向。这样,第一个方法和第二个方法就不能在事务中共享同一物理连接。换言之,就是需要在全局事务中运行 XA 数据源。
当这两个方法都尝试访问同一个表时,会遇到数据库死锁的问题。因此,共享连接是由 CMP 方法中定义的访问意向确定的。
- 在 CMP Bean 和 BMP Bean 之间共享连接
请记住,首先要验证设置相同连接属性的 BMP Bean 和 CMP Bean 的 getConnection 方法。要与 CMP Bean 资源的认证类型相匹配,请将 BMP Bean 资源的认证类型设置为“容器管理的”,通过在部署描述符中指定 res-auth = Container 来进行此设置。
此外,使用下列其中一个选项来确保 Bean 类型之间的连接共享:- 在 CMP Bean 方法和 BMP Bean 方法上定义相同的访问意向。由于使用了相同的访问意向,它们就能共享同一物理连接。使用此选项的优点在于后端对于 BMP Bean 是透明的。但是,由于此选项使用 WebSphere® 扩展 API 来处理隔离级别,所以它还使得 BMP 不可移植。有关更多信息,请参阅“示例:使用 IBM® 扩展 API 访问数据以在容器管理的和 Bean 管理的持久性 Bean 之间共享连接”主题中的代码示例。
- 确定 CMP Bean 方法上访问意向使用的隔离级别,然后使用对资源引用指定的相应隔离级别来查找数据源和连接。选择使用此方法时更多采用的是手动处理,且不同数据库的隔离级别可能也不相同。有关更多信息,请参阅主题“访问意向隔离级别和更新锁定”和主题“隔离级别和资源引用”部分中的隔离级别和访问意向映射表。
- 在 CMP 和 Servlet 或会话 Bean 使用的 JDBC 应用程序之间共享连接确定访问意向在 CMP Bean 方法上使用的隔离级别,然后使用对资源引用指定的相应隔离级别来查找数据源和连接。 有关更多信息,请参阅主题“访问意向隔离级别”和主题“隔离级别和资源引用”部分。
确定共享的因子
此处的列表不是详尽的列表。产品在不同环境下可能共享连接也可能不共享连接。- 仅用相同的资源引用 (resource-ref)(它将 res-sharing-scope 指定为“可共享”)获取的连接才有可能进行共享。资源引用属性 res-sharing-scope 和 res-auth 以及 IBM 扩展 isolationLevel 帮助确定是否能够共享连接。IBM 扩展
isolationLevel 存储在 IBM 部署描述符扩展文件中;例如:ibm-ejb-jar-ext.xmi。
支持的配置: 对于 IBM 扩展文件和绑定文件,根据您使用的是 Java EE 5 之前的应用程序或模块还是 Java EE 5 或之后的应用程序或模块,.xmi 或 .xml 文件扩展名有所不同。IBM 扩展文件或绑定文件将命名为 ibm-*-ext.xmi 或 ibm-*-bnd.xmi,其中 * 是扩展文件或绑定文件的类型,例如,app、application、ejb-jar 或 web。存在下列条件:
然而,Java EE 5 或更高版本的模块可以在包含 Java EE 5 之前的文件并使用 .xmi 文件扩展名的应用程序中存在。
ibm-webservices-ext.xmi、ibm-webservices-bnd.xmi、ibm-webservicesclient-bnd.xmi、ibm-webservicesclient-ext.xmi 和 ibm-portlet-ext.xmi 文件继续使用 .xmi 文件扩展名。
sptcfg - 您只能共享使用相同属性请求的连接。
- 只有不同的组件实例位于同一个事务(容器或用户启动的事务)中时,才能在它们之间共享连接。
- 仅在共享范围内共享连接。Current®共享范围包含事务和 LocalTransactionContainment (LTC) 范围。
- LTC 范围中的连接共享规则:
- 对于可共享的连接,在单个组件实例中仅允许连接复用。当对连接进行以下操作时发生连接复用:获取、使用、落实/回滚、关闭;获取、使用、落实/回滚、关闭。注意,如果您使用 ContainerAtBoundary 的 LTC 解析控制,那么由于该操作是由容器处理的,因此无需任何启动/落实。
第二次获取返回的连接与第一次获取返回的连接相同(如果使用相同的属性)。因为串行使用连接,所以一次只使用基本物理连接的一个连接句柄,这样并不发生真正的连接共享。术语“复用”更准确。
更为重要的是,包含两次获取操作的 LocalTransactionContainment 范围不完整;在 ManagedConnection 对象上未调用 cleanUp() 方法。因此第二次获取操作继承了在第一次 getConnection() 调用期间设置的所有连接属性。
- 对于可共享的连接,在单个组件实例中仅允许连接复用。当对连接进行以下操作时发生连接复用:获取、使用、落实/回滚、关闭;获取、使用、落实/回滚、关闭。注意,如果您使用 ContainerAtBoundary 的 LTC 解析控制,那么由于该操作是由容器处理的,因此无需任何启动/落实。
- 事务(容器管理的事务 (CMT),Bean 管理的事务 (BMT) 或 LTC 事务)之间的可共享连接遵循以下高速缓存规则:
- 总之,因为一个连接句柄的用户不可能预期另一个连接句柄用户将做什么更改,因此不允许在可共享的连接上设置属性。此局限性是 Java Platform, Enterprise Edition (Java EE) 标准的一部分。
- 资源适配器的普通用户可以通过在 ConnectionSpec 中传递连接属性以在连接工厂 getConnection() 调用上设置这些属性。
但是,在某事务期间设置的连接属性,不能保证在下一事务中使用时还是原样。因为在共享范围外共享连接是无效的,事务结束时连接句柄从当前与其相关联的物理连接上移出。该物理连接返回到空闲连接池。进入空闲池之前清除连接句柄。下次使用句柄时,它自动与适当的连接相关联。连接的适当性基于安全性登录信息、连接属性和扩展资源引用中指定的隔离级别(对于 JDBC API),它们是在返回当前句柄的原始请求中传递的。连接上设置的任何属性在获取后都将丢失。
- 对于 JDBC 用户,应用程序服务器提供了一个扩展,该扩展使您能够通过 ConnectionSpec 传递连接属性。
在局部事务范围中设置属性和共享连接时必须谨慎。确保您设置产生的行为是共享此连接的其他组件所期待的。
- 您无法使用全局事务中的关系资源适配器来为 JDBC API 设置可共享连接的隔离级别。产品为资源引用提供扩展以使您能指定隔离级别。如果您的应用程序需要使用多个隔离级别,那么创建多个资源引用,并将它们映射至同一数据源或连接工厂。
最大连接共享
要使应用程序拥有最多的连接共享机会,请确保将每个组件的局部事务包含 (LTC) 解析器属性设置为 ContainerAtBoundary。 此设置指定是组件容器而不是应用程序代码解析 LTC 范围中的所有资源管理器局部事务 (RMLT)。第一次在 LTC 范围内使用连接时,容器将开始 RMLT,并且会在 LTC 范围末尾自动完成它。
请参阅主题“配置事务部署属性”以获取有关设置事务解析控制和其他属性的指示信息。
连接共享违例
- 与受管连接相关联的连接句柄数大于一。
- 受管连接与局部事务或 XA 事务相关联。
根据受管连接变为不可共享连接的时间和方式,组件和 J2C 运行时可能都需要检测此共享违例异常。如果是由于通过连接句柄进行的操作(例如,更改隔离级别),受管连接才变为不可共享连接,那么该组件需要处理此异常。如果由于某个组件与连接句柄的交互,受管连接在没有被应用程序服务器认可的情况下变为不可共享连接,那么资源适配器可通过发出共享违例异常来拒绝创建连接句柄。