【问题标题】:Application continuity with Universal Connection Pool java JDBC Oracle 12c通用连接池 java JDBC Oracle 12c 的应用程序连续性
【发布时间】:2018-09-11 13:24:18
【问题描述】:

我正在尝试使用 Oracle 12c 数据库和 Oracle UCP(通用连接池)实现应用程序连续性。根据官方文档,我在我的应用程序中实现了以下内容。我在我的应用程序中使用 ojdbc8.jar 以及等效的 ons.jar 和 ucp.jar。

PoolDataSource  pds = oracle.ucp.jdbc.PoolDataSourceFactory.getPoolDataSource();

根据 oracle 文档的属性:

pds.setConnectionFactoryClassName("oracle.jdbc.replay.OracleDataSourceImpl");
pds.setUser("username");
pds.setPassword("password");
pds.setInitialPoolSize(10);
pds.setMinPoolSize(10);
pds.setMaxPoolSize(20);
pds.setFastConnectionFailoverEnabled(true);
pds.setONSConfiguration("nodes=IP_1:ONS_PORT_NUMBER,IP_2:ONS_PORT_NUMBER");
pds.setValidateConnectionOnBorrow(true);
pds.setURL("jdbc:oracle:thin:@my_scan_name.my_domain_name.com:PORT_NUMBER/my_service_name");
// I have also tried using the TNS-Like URL as well. //

但是,我无法实现应用程序的连续性。当我关闭运行我的数据库服务的 RAC 节点时,我希望重播一些正在进行的事务。我观察到我的服务迁移到集群中的下一个可用 RAC 节点,但是,我的进行中事务失败。这里期望发生的是驱动程序将自动重新启动失败的正在进行的事务。但是,我没有看到这种情况发生。我触发的查询是数据库,有时我看到它们在数据库端再次被触发,但我们在客户端看到连接关闭异常

根据一些文档,应用程序连续性允许应用程序屏蔽用户的中断。我的疑问是,我对应用程序连续性将重放发生中断时正在进行的 SQL 语句的理解是否正确,或者应用程序连续性的真正含义是什么。

我参考了一些博客,例如this, https://martincarstenbach.wordpress.com/2013/12/13/playing-with-application-continuity-in-rac-12c/

此处提到的示例似乎并非用于重放运行中的 SQL 语句。

应用程序连续性是否能够在中断期间重放运行中的 SQL 语句,或者 FCF 和应用程序连续性是否仅恢复连接对象的状态并使其在中断发生后可供用户使用。如果前面是正确的,那么请指导我,如果我的代码中的应用程序级别设置中缺少任何使我无法实现重播的内容。

【问题讨论】:

  • 视情况而定。我确实测试过,似乎 JDBC 驱动程序对记住的更改量有一些内部限制。如果超过此阈值,当连接被终止时,您将收到 java.sql.sqlRecoverableException。我无法找到并记录此阈值的值。

标签: java oracle transactions oracle12c ojdbc


【解决方案1】:

是的,您的理解是正确的。使用重播驱动程序,应用程序连续性可以重播正在进行的工作,以便应用程序看不到中断并且应用程序可以继续,这就是该功能的名称。从应用程序中唯一可以看到的是导致中断的 JDBC 调用的轻微延迟。同样可见的是 JDBC 端的内存使用量增加,因为驱动程序维护了一个调用队列。幕后发生的事情是,一旦中断,您的物理 JDBC 连接将被一个全新的连接所取代,并且重放驱动程序将重放其调用队列。

现在可能会出现重放失败的情况。例如,如果数据已更改,重播将失败。如果您在“请求”中有多个事务,重播也将被禁用。 “请求”从池中借用连接时开始,并在它返回池时结束。通常,“请求”与 servlet 执行相匹配。如果在此请求中您有多个“提交”,则重播将在运行时禁用,重播驱动程序将停止排队。另请注意,必须禁用自动提交。

[我是设计和实现此功能的 Oracle 团队的一员]

【讨论】:

  • 进行中的查询是不是也意味着JDBC ResultSet上的游标恢复到失败前的位置。 (例如,如果一个查询即将返回 100 万个结果,并且我们已经向上移动到假设第 10000 行,那么光标将恢复到这个位置?)
  • 感谢您明确@Jean。我也尝试过关闭自动提交。但是,我无法达到预期的效果。此外,我提到的大多数文档和博客都没有提供任何使用 UCP 时重放的具体示例。您能否指出此类说明使用 UCP 重播进行中交易的文档/博客/示例?
  • @AkshayGehi 是的,所有 JDBC 调用都会重放,包括 resultSet.next(),因此位置将重置为中断前的位置。
  • @RishiD Martin 的博客有一个不错的代码示例:martincarstenbach.wordpress.com/2013/12/13/…
  • 在查询数据库时,通过断开我的机器与 LAN 的连接来进行重播。暂停几秒钟,然后重新启动查询并恢复返回数据。在触发查询的节点上使用立即关闭时,收到以下错误并且查询未重播:无法从数据源获取连接:java.sql.SQLException:侦听器拒绝连接并出现以下错误:ORA- 12521, TNS:listener 当前不知道连接描述符中请求的实例。使用 SCAN 名称连接数据库
【解决方案2】:

我认为 jdbc 连接字符串可能是你的问题:

pds.setURL("jdbc:oracle:thin:@my_scan_name.my_domain_name.com:PORT_NUMBER/my_service_name");

您正在使用所谓的EZConnect 字符串,但 AC 不支持。

Alias (or URL) = (DESCRIPTION=
(CONNECT_TIMEOUT= 120)(RETRY_COUNT=20) RETRY_DELAY=3)(TRANSPORT_CONNECT_TIMEOUT=3)
(ADDRESS_LIST=(LOAD_BALANCE=on)
(ADDRESS=(PROTOCOL=TCP)(HOST=primary-scan)(PORT=1521)))
(ADDRESS_LIST=(LOAD_BALANCE=on)
(ADDRESS=(PROTOCOL=TCP)(HOST=secondary-scan)(PORT=1521)))
(CONNECT_DATA=(SERVICE_NAME=gold-cloud)))

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-10-19
    • 2011-10-10
    • 2018-09-09
    • 2014-03-31
    • 2021-07-11
    • 2011-03-06
    • 2012-03-21
    • 2017-06-04
    相关资源
    最近更新 更多