转Oracle:OC4J 10g 10.1.3 数据源中的连接高速缓存

在部署 J2EE 应用程序中最耗时的操作之一就要数建立到数据库的连接了。应用程序服务器通常提供连接高速缓存或者连接池以尽量减小这一任务所带来的开销。(尽管术语“连接高速缓存”和“连接池”在 JDBC 中有不同的含义,这里我们将借鉴这些术语。)

Oracle Application Server Containers for J2EE 10g (OC4J) 9.0.4 中,根据数据源的类型采用了不同的连接高速缓存机制。然而,OC4J 10g 10.1.3 在数据源中引入了几项关键改进,其中之一就是新的连接高速缓存机制。它是所有 Oracle 数据源的统一连接高速缓存机制,并提供集成的真正应用集群 (RAC) 故障切换支持。 该机制利用了 Oracle 数据库 10g 的新 JDBC 连接高速缓存特性。(注意:OC4J 10g 10.0.3 最近改版为 10.1.3,而且下一个公开发行版将反映这一变化。这里对 10.1.3 版的所有引用对当前可用的 10.0.3 版也适用。)

这篇技术说明提供了对这一新特性的详细描述,并阐明了它在应用程序中的用法。

OC4J 10g 10.1.3 数据源:概要 OC4J 10g 10.1.3 已经简化了数据源分类:现在只有两种类型的数据源:受管理的数据源原生数据源 受管理的数据是由 OC4J 管理的数据源。具体来讲,受管理的数据源就是一个 OC4J 提供的 java.sql.DataSource 实现,充当 JDBC 驱动程序或数据源的绕接器。J2EE 组件通过 JNDI 访问受管理的数据源,而还不知晓该数据源竟是一个绕接器。OC4J 为受管理的数据源提供关键的系统基础架构,如全局事务管理、连接高速缓存、通过 JMX 的动态配置以及错误处理。 原生数据源还实现了 java.sql.DataSource 接口,这些数据源由 JDBC 驱动程序供应商如 Oracle 和 DataDirect 提供。原生数据源根本不用 OC4J 绕接。 下表归纳了受管理的和原生数据源之间的主要差异:

受管理的数据源 原生数据源
从数据源检索到的连接可以参与全局事务

数据源利用 OC4J 的连接池和语句高速缓存
从通过一个 OC4J 连接代理绕接的数据源返回的连接

连接高速缓存

连接高速缓存(通常在中间层实现)允许在不同的应用程序间共享一个数据库连接。 中间层维护着一个预先分配的物理数据库连接池,应用程序可以使用这些连接来与数据库服务器交互。 当应用程序请求数据库连接时,中间层首先查看连接池中是否有符合该请求的可用连接;如果有,则中间层就返回其中的一个连接。

当请求连接而连接高速缓存中没有空闲的池连接实例时,则会创建新的池连接实例。 “空闲”的池连接实例是指该实例当前没有与其相关的逻辑连接实例;换言之,就是指该池连接实例的物理连接没有使用。 当应用程序关闭此连接时,中间层就会把此连接送回到池中,从而避免在发生连接请求执行打开新数据库连接这样耗费大量资源的任务。

高速缓存中的池连接都有一些连接特性或属性(数据库名、服务器名、端口号等等)。大多数连接高速缓存都包括一个连接池,其中包含用于同一数据库和同一用户名的一个或多个连接。

OC4J 10g 10.1.3 数据源中的连接高速缓存

OC4J 10g 10.1.3 数据源中的高速缓存利用了 Oracle 数据库 10g JDBC 提供的所有新高速缓存特性 — 特别是新的隐式连接高速缓存中的特性。

在 Oracle 数据库 10g 之前,将 Oracle JDBC 的连接高速缓存接口命名为 OracleConnectionCache,而将其实现命名为 OracleConnectionCacheImpl。此高速缓存只为指定用户名提供到特定数据库的物理连接池的支持。在 Oracle 10g JDBC 中,不建议使用 OracleConnectionCache 接口和 OracleConnectionCacheImpl 类,从而向一个更强健的以性能为导向的体系结构转变。设计了新的体系结构,这样就可以将连接高速缓存透明地集成到数据源中。 隐式连接高速缓存是数据源的一个新的符合 JDBC 3.0 的连接高速缓存实现。 它通过提供对高速缓存的透明访问,不再需要应用程序开发人员编写自己的高速缓存实现。 它还支持多用户,并能基于用户定义的属性请求连接。 隐式连接高速缓存影响着物理和逻辑连接的概念。 它使用标准 OracleDataSource API 来获得连接,并在底层应用程序启用高速缓存后处理连接缓存中的所有连接。物理连接是由数据库返回的实际连接,而逻辑连接可以看作是高速缓存用于处理物理连接的句柄。 隐式连接高速缓存还提供一个新类 — OracleConnectionCacheManager,这样应用程序就可以使用其丰富的管理 API 组来有效地创建、管理和维护连接高速缓存。应用程序可以通过单个 OracleConnectionCacheManager 实例或者通过与高速缓存相关联的 OracleDataSource 来管理它们的高速缓存。这些 API 广泛应用于 OC4J 10g 10.1.3 中。 还为用户提供了一个回调机制来定义高速缓存行为和确定通过用户定义的连接属性检索到的确切连接。 新的连接高速缓存机制还包括集成的为 Oracle 数据库提供的 RAC 故障切换支持。 它通过监听数据库生成的 UP/DOWN RAC 事件实现了与数据库自身同步的快速、高效的连接高速缓存中连接的连接故障切换。事件发布/订阅机制由 Oracle 通知服务 (ONS) 提供。此类支持只用于 RAC 数据库,这是由于 RAC 数据库支持所需故障切换事件的生成。 与 OC4J 10g 10.1.3 数据源中的新连接高速缓存相关的一些好处包括:
  • 驱动程序独立
  • 连接高速缓存的透明访问
  • 每个缓存可以有多个用户和多个口令
  • 符合 JDBC 3.0 标准
  • 连接回收与陈旧连接的刷新
  • 基于属性搜索连接
  • 启用多个缓存的数据源
  • 连接高速缓存回调机制
  • 集成的对 RAC 快速连接故障切换的支持。
应用程序可以轻松地利用 OC4J 10g 10.1.3 数据源中的新连接高速缓存功能。 该应用程序只需配置数据源和其连接高速缓存,从该高速缓存获得一个连接,使用该连接实现一些业务逻辑,并在使用后把该连接返回该高速缓存。应用程序还可以使用 OracleConnectionCacheManager 重新初始化一些连接属性。基本上说,应用程序仍将像通常那样使用数据源,如数据源设置和查找。 此外,应用程序将配置它们要使用的连接高速缓存。对于大部分应用程序,这一目标是通过对受管理的数据源及原生数据源的简单配置属性更改而声明性实现的。对于由 Oracle 10g JDBC 提供的原生数据源,这也可以通过调用特定的连接高速缓存管理 API 以编程方式实现。 同样值得注意的是,这些 API 就是 OC4J 在提供其自己的连接高速缓存时使用的 API。 以声明的方式配置连接高速缓存 在 OC4J 10g 10.1.3 中,指定连接高速缓存属性相对简单一些。 对于大多数应用程序来说,此种指定是在 data-sources.xml 配置文件中声明式完成的。 受管理的数据源

对于受管理的数据源,配置连接高速缓存可以分两个步骤完成:

  1. 使用 <connection-pool> XML 元素在 data-sources.xml 中添加一个连接高速缓存,指定其所需属性的详细信息。
  2. 在同一文件中的每个 <managed-data-source> XML 元素中使用“connection-pool-name”属性,指定这个受管理的数据源用于汇聚其连接的连接高速缓存的名称。

第 2 步相对简单,因此我们集中看第 1 步。<connection-pool> 元素具有以下属性(每个属性都是可选的,除非标记为“必要”):

属性名称 说明 默认值
name (Required) The name of the connection pool; must be unique

min-connections 连接池将维护的最小连接数
0
max-connections 在任何给定时间能够打开的连接的最大数量。值为 0 或小于 0(表示没有最高限制)。
0
initial-limit
在初次创建或重新初始化高速缓存时设置连接高速缓存的大小。当将该属性设置为大于 0 的值,则可以预先创建许多连接并可随时使用。这个属性通常用于在将缓存设为其最优大小时减少“加速”时间。
0
used-connection-wait-timeout
等待客户端释放使用的连接所需的时间(秒)。该属性只适用于已从数据源获得了最大数量的连接且这些连接都在使用的情形。在这种情况下,当一个客户端尝试从连接池中借一个连接而所有连接都在使用中时,连接池将等待将一个连接释放回池中。
60
inactivity-timeout
将一个未使用的连接从连接池中移除前其不活动的时间(秒)
60
login-timeout
此数据源在尝试连接到一个数据库时将等待的时间的最大值(秒)。值为零说明使用默认的系统超时(如果有的话,否则不会超时)。
0
connection-retry-interval
在重试一个失败的连接尝试前等待的间隔(秒),与“max-connnect-attempts”一起使用
1
max-connect-attempts
重试进行一个连接的次数,与“connection-retry-interval”一起使用
3
validate-connection 表明从连接池借用一个连接时是否根据数据库对其进行验证。值为“true”表明从连接池借用一个连接时,执行由“validate-connection-statement”声明的语句来验证此连接是否有效;值为“false”表明从连接池借用连接时不会执行任何语句。与“validate-connection-statement”一起使用。
false
validate-connection-statement
从连接池借用连接时执行的 SQL 语句。与“validate-connection”一起使用。

num-cached-statements 应该为每个连接缓存的最大语句数。任何大于 0 的值自动为数据源启用语句缓存。
0
time-to-live-timeout
一个使用的连接保持活动的最长时间(秒)。 当这个超时时,所使用的连接会无条件地关闭,取消相关语句句柄,并将此连接返回连接池。值为 –1 表示这个特性没有启用。
-1
abandoned-connection-timeout
只适用于 Oracle 数据库。abandoned-connection-timeout 与 inactivity-timeout 类似,但是前者用在逻辑连接上。在设置了该属性时,JDBC 监视这个逻辑连接(由用户从高速缓存借来的连接)上的 SQL 数据库活动。例如,当在此连接上调用 stmt.execute() 时,会注册一个检测信号 (heart beat) 以表示这个连接是活动的。只监视导致数据库执行调用的地方的检测信号以降低监视成本。如果一个连接不活动时间已达到某一指定值,则将底层的 PooledConnection 回收并返回缓存以重新使用。默认值为 -1,即这个特性未生效。
-1
disable-server-connection-pooling
确定是否禁用应用服务器的连接池。之所以提供这个属性是因为一些 JDBC 驱动程序本身就提供了连接池。如果 JDBC 驱动程序是 Oracle 且驱动程序正在使用隐式连接高速缓存,则忽略这个属性。
false
property-check-interval
只适用于 Oracle 数据库。高速缓存后台程序线程执行超时限制的时间间隔(秒)。
900
lower-threshold-limit
只适用于 Oracle 数据库。连接池上较低的阈值限制。默认为 max-connections 的 20%。
20%

除了上面的属性,每个 <connection-pool> 元素都必须包含一个 <connection-factory> 元素,该元素定义用于为连接池创建连接的连接工厂 (connection factory)。它有如下属性(每个属性都是可选的,除非标记为“必要”):

属性名称 说明 默认值
factory-class (必要)定义连接工厂 (connection-factory) 实现的全路径类。它必须是 java.sql.Driver、javax.sql.DataSource、javax.sql.ConnectionPoolDataSource 或 javax.sql.XADataSource 的一个实现。

url (必要)用来连接底层数据库的 url

user 用来连接数据库的默认用户
password
用来连接数据库的默认口令

login-timeout
尝试连接数据库时等待的最长时间(秒)。值为零表示此超时使用默认的系统超时(如果有的话),否则不会超时。
0

现在我们来看一些具体的例子:

使用 XADataSource 连接工厂的受管理数据源


<managed-data-source
jndi-name="jdbc/ManagedXADS"
description="Managed DataSource"
connection-pool-name="myConnectionPool"
name="ManagedXADS"/>

<connection-pool
name="myConnectionPool"
min-connections="10"
max-connections="30"
inactivity-timeout="30"
<connection-factory 
factory-class="oracle.jdbc.xa.client.OracleXADataSource"
user="scott"
password="tiger"
url="jdbc:oracle:thin:@localhost:1521:oracle"/>
<property name="nativeXA" value="true"/>
</connection-factory>
<!- <connection-pool> ?
        
使用 DataSource 连接工厂的受管理数据源 <managed-data-source jndi-name="jdbc/ManagedDS"
description="Managed DataSource">
connection-pool-name="myConnectionPool"
name="ManagedDS"/>
<connection-pool name="myConnectionPool" min-connections="10" max-connections="30" inactivity-timeout="30" <connection-factory factory-class="oracle.jdbc.pool.OracleDataSource" user="scott" password="tiger" url="jdbc:oracle:thin:@localhost:1521:oracle"/> <property name="loginTimeout" value="30"/> </connection-factory> <!- <connection-pool> ?
原生数据源

对于原生 Oracle 数据源,配置连接高速缓存主要是以编程的方式完成。(更多详细信息参见接下来的部分。) 连接缓存的声明式配置也可分两个步骤完成:

  1. 将“oracle.jdbc.pool.OracleDataSource”用作 data-sources.xml 中每个 <native-data-source> XML 元素的“data-source-class”属性的值。这就是在 Oracle 10g JDBC 驱动程序中进行隐式连接高速缓存时的数据源实现。
  2. <native-data-source> 内的 <property> 元素中指定任何缓存特有的属性来控制连接高速缓存的行为。
对于第 2 步,下列属性名称可用于 <property> 元素的指定:

名称 类型 说明
connectionCacheName String 高速缓存的名称;一旦创建则无法更改。
connectionCachingEnabled Boolean 是否启用隐式连接高速缓存
fastConnectionFailoverEnabled Boolean 是否启用 RAC 快速连接故障切换

下面是一个具体的例子:
<native-data-source
name="nativeDataSource"
jndi-name="jdbc/nativeDS"
description="Native DataSource"
data-source-class="oracle.jdbc.pool.OracleDataSource"
user="scott"
password="tiger"
url="jdbc:oracle:thin:@localhost:1521:oracle">
<property name="connectionCacheName" value="ICC1"/>
<property name="connectionCachingEnabled" value="true"/>
<property name="fastConnectionFailoverEnabled" value="false"/>
</native-data-source>
以编程方式配置连接高速缓存

受管理的数据源 在使用受管理的数据源时,连接高速缓存是通过数据源配置文件以声明的方式指定的。 这在“以声明的方式配置连接高速缓存”中有详细说明。 原生数据源 对于 Oracle 10g JDBC 提供的原生数据源,应用程序有附加的选项来以编程方式配置连接高速缓存。由于高速缓存是 OC4J 10g 10.1.3 统一的 Oracle 数据源,从而使它并不比声明式方法难。 有了这个选项,应用程序又有了两种利用连接高速缓存的方法:(1) 依赖于 OracleDataSource 中的隐式连接高速缓存行为,并在数据源上设置连接高速缓存属性;(2) 直接使用连接高速缓存管理器 OracleConnectionCacheManager API。 对于 (1),OracleDataSource 类为连接高速缓存属性提供下列 setter() 和 getter() 方法:
  • String getConnectionCacheName()
  • void setConnectionCacheName(String cacheName)
  • java.util.Properties getConnectionCacheProperties()
  • void setConnectionCacheProperties(java.util.Properties cp)
这里的每个连接高速缓存属性对应“以声明的方式配置连接高速缓存”中的受管理数据源情况下的一个配置属性 — 尽管真正的属性名称可能略有不同。 对于 (2),OracleConnectionManager 提供了应用程序可用于管理可用连接高速缓存的 API。 以下是其中的一些 API。(关于 (1) 和 (2) 的更多详细信息,请参考 Oracle 数据库 10g JDBC 开发人员指南与参考。)
  • static OracleConnectionCacheManager getCacheManagerInstance()
  • void createCache(String cacheName, javax.sql.DataSource ds, Properties cacheProperties)
  • String createCache(javax.sql.DataSource ds, Properties cacheProperties)
  • void removeCache(String cacheName, int mode)
  • void refreshCache(String cacheName, int mode)
  • java.util.properties getCacheProperties(String cacheName)
下面的 configureDataSource 方法显示了与高速缓存相关联的 OracleDataSource 的一般设置。它用主机名称、用户名称、密码等的相应值配置 Datasource。它还加载一些存储在 Connection.properties 文件中的连接属性:
private void configDataSource(OracleDataSource ods) {
......
/* Load the properties file to get the connection properties  
* from the Connection.properties file
 */
Properties prop = this.loadParams("Connection"); 
ods.setDriverType("thin");
ods.setHostName("localhost");
ods.setNetworkProtocol("tcp");
ods.setPortNumber   (1521);
ods.setUser("scott");
ods.setPassword("tiger");
ods.setServiceName("oracle");
ods.setConnectionProperties(prop);
......
}   
下面的代码演示上面的方法 (1)。 方法 initializeConnectionCacheDataSrc 启用连接高速缓存,并且设置了高速缓存的名称,该名称唯一地标识该连接高速缓存。然后它在 OracleDataSource 上设置一些连接高速缓存属性,这些属性将被传递给高速缓存。
private void configCachingInDataSource(OracleDataSource ods)
throws SQLException
{
  ......
ods.setConnectionCachingEnabled(true);  // Enable caching
ods.setConnectionCacheName(CACHE_NAME); // Set the cache name   

Properties cacheProperties = new Properties();

cacheProperties.setProperty("MinLimit", "1");   // Set Min Limit for the Cache 
cacheProperties.setProperty("MaxLimit", "15");  // Set Max Limit for the Cache 
cacheProperties.setProperty("InitialLimit", "10");    // Set the Initial Limit  

ods.setConnectionCacheProperties(cacheProperties);

}
下面的代码演示上面的方法 (2):如何使用 OracleConnectionCacheManager 创建一个连接高速缓存。 createCache 方法用于创建高速缓存,同时用于接收 OracleDataSource 高速缓存名称和高速缓存 Properties 对象。 请注意,连接高速缓存属性是在创建连接高速缓存时设置的:
private void initializeConnectionCache() throws Exception {
  .............. 
 
OracleDataSource ods = new OracleDataSource();

this.configureDataSource(ods);
ods.setConnectionCachingEnabled(true);  // Enable caching

// Initialize the Connection Cache
OracleConnectionCacheManager connMgr =
OracleConnectionCacheManager.getConnectionCacheManagerInstance();
  
/* This object holds the properties of a cache and is passed to the 
* ConnectionCacheManager while creating the cache.
   */
Properties cacheProperties = new Properties();

cacheProperties.setProperty("MinLimit", "1");   // Set Min Limit for the Cache 
cacheProperties.setProperty("MaxLimit", "15");  // Set Max Limit for the Cache 
cacheProperties.setProperty("InitialLimit", "10");    // Set the Initial Limit  

/* Create the cache by passing the cache name, data source and the 
* cache properties 
   */
connMgr.createCache(CACHE_NAME, ods, properties);
总结

数据库连接高速缓存是 Oracle 应用服务器一个功能强大的部分。有了 Oracle 数据库 10g 简化的数据源配置和集成的连接高速缓存管理,OC4J 10g 10.1.3 为构建分布式 J2EE 应用程序提供了一个可伸缩的平台。

魔兽就是毒瘤,大家千万不要玩。
原文地址:https://www.cnblogs.com/tracy/p/1717018.html