通用连接池java JDBC Oracle 12c的应用程序连续性

时间:2018-09-11 13:24:18

标签: java oracle transactions oracle12c ojdbc

我正在尝试通过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语句的理解是正确的,还是其他方面应用程序连续性的真正含义?

我已经提到过一些这样的博客, https://martincarstenbach.wordpress.com/2013/12/13/playing-with-application-continuity-in-rac-12c/

此处提到的示例似乎并不旨在重播运行中的SQL语句。

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

2 个答案:

答案 0 :(得分:3)

是的,您的理解是正确的。使用重播驱动程序,Application Continuity可以重播正在进行的工作,以便应用程序看不到中断,并且应用程序可以继续运行,因此可以使用功能名称。在应用程序中唯一可见的是导致中断的JDBC调用略有延迟。还可以看到的是,由于驱动程序维护了一个调用队列,JDBC端的内存使用量有所增加。幕后情况是,一旦中断,您的物理JDBC连接将被全新的连接取代,并且重播驱动程序将重播其调用队列。

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

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

答案 1 :(得分:1)

我认为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)))