Java中限制JCA连接高效利用的应用程序使用场景

对企业">信息系统 (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 连接的使用具有非常重要的作用。遵循一些使用模式并拥有连接行为的知识,这些可以帮助您避免耗尽连接池和帮助提高可伸缩性。

时间: 2024-09-17 09:46:18

Java中限制JCA连接高效利用的应用程序使用场景的相关文章

java中有关get方法的使用(具体程序分析)

问题描述 java中有关get方法的使用(具体程序分析) 最近在学习java,用的徐彩霞的java基础教程. 有个例子不太明白. /* /注释部分的get部分有和没有结果一样,想知道为什么要用get? 又必须要用的情况吗? 刚学,懂得比较少,谢谢了~ class Person { private String name; private int age; private void talk() { System.out.print("I'm "+name+" and &quo

如何在应用程序中使用JCA连接实现可伸缩性

简介 对企业信息系统 (EIS) 的关系和过程访问的连接管理架构都基于 Java EE Connector Architecture (JCA) 规范.Connection Manager (CM) 将一个应用服务器中的连接加入池中进行管理,既能够管理通过 JCA 规范定义的资源适配器所获取的连接,也能够管理通过 Java 数据库连接 (JDBC) 规范定义的数据源所获取的连接.IBM WebSphere Application Server 支持管理员建立后端连接池,以便在一个应用服务器上共享

Java中使用设计模式来优化命令行交互程序的开发

人机交互的方式最初起始于命令行交互,虽然图形界面的交互方式应用越来越广泛,可是命令行交互仍然有着它不可替代的地位.命令行交互程序是以命令行方式进行的http://www.aliyun.com/zixun/aggregation/11432.html">人机交互,即用户按着程序的提示,一步步进行输入,而程序负责解释并最终执行指令. 本文以一个简单的部署 war 包的实例,说明在命令行交互程序设计中遇到的问题,以及如何使用设计模式来解决这些问题. 实例简介 在实例中,命令行交互程序给出了一组问

string-java 中 String 类连接问题

问题描述 java 中 String 类连接问题 String str1 = "aa" ; String str2 = "bb" ; String str3 = "aa" + "bb" ; String str4 = str1 + str2 ; boolean b =(str3 == str4); System.out.println(b); 这里b为什么是false , 有那个大侠能否帮忙回答下? 解决方案 编译的时候,aa

Java中函数的递归调用

说到递归,java中的递归和C语言中也是很相似的,在Java中,递归其实就是利用了栈的先进后出的机制来描述的. public class HelloWorld { public static void main(String[] args){ // Scanner s = new Scanner(System.in); // System.out.println("请输入一个数字"); // int num = s.nextInt(); int c = 10 , d = 20 ; sw

谈谈JAVA中的调用方式

很多书籍都说Java支持传引用调用的方式,类似于C++中的Person &a引用调用,而近来编程遇到一系列问题让我对此产生了怀疑,于是将这些方法一一列出,我们来一起看看JAVA中的调用方式:   看下面的程序:  class Person {      private String name;//姓名     private String sex;//性别     public Person(String x, String y) {         this.name = x;        

java 中的常用类

Java 中的包装类 相信各位小伙伴们对基本数据类型都非常熟悉,例如 int.float.double.boolean.char 等. 基本数据类型是不具备对象的特性的,比如基本类型不能调用方法.功能简单..., 为了让基本数据类型也具备对象的特性, Java 为每个基本数据类型都提供了一个包装类,这样我们就可以像操作对象那样来操作基本数据类型. 包装类主要提供了两大类方法: 1. 将本类型和其他基本类型进行转换的方法 2. 将字符串和本类型及包装类互相转换的方法         Integer

java中数据交换的问题

问题描述 java中数据交换的问题 晚上在写程序的时候需要用到交换数据,所以我就主类里面写了一个swap, 但是在调用之后发现数据没有交换成功,可是在swap里面数据的确交换成功了呀, 不知道是什么原因,下面贴出代码: public static void main(String[] args){ int a,b; a = 4; b = 5; swap(a,b); System.out.println(a+","+b); } public static void swap(int a,

Java 中基本类型和字符串之间的转换

Java 中基本类型和字符串之间的转换 在程序开发中,我们经常需要在基本数据类型和字符串之间进行转换. 其中,基本类型转换为字符串有三种方法: 1. 使用包装类的 toString() 方法 2. 使用String类的 valueOf() 方法 3. 用一个空字符串加上基本类型,得到的就是基本类型数据对应的字符串 再来看,将字符串转换成基本类型有两种方法: 1. 调用包装类的 parseXxx 静态方法 2. 调用包装类的 valueOf() 方法转换为基本类型的包装类,会自动拆箱 PS:其他基