Oracle DB - 应用程序连续性 - 如何测试?

时间:2015-11-23 08:36:18

标签: oracle datasource oracle12c replay continuity

如何测试/ POC应用程序连续性概念。我尝试使代码保持连接,以便应用程序无法获取连接,并尝试从池中获取。我确信这不是测试应用程序连续性的正确方法,但我不知道如何创建适当的场景。

这是在事务进行过程中关闭db的唯一方法吗?

我使用下面的代码来模拟AC,其中一个过程在20个线程中被调用20次,每次都有一个新的连接。我正在创建一个场景,其中一个线程进入并等待连接,超时因为没有及时连接,然后退休以获得连接,这是一个正确的AC测试。 (以下是测试类)

package com.ac;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

import java.sql.Connection;
import java.sql.SQLException;
import java.sql.Statement;

import oracle.ucp.jdbc.PoolDataSourceFactory;
import oracle.ucp.jdbc.PoolDataSource;
import oracle.ucp.jdbc.ValidConnection;

import java.sql.ResultSet;

public class App {

    public static void main(String[] args) {
        try {
            new App().acSimulation();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public void acSimulation() throws Exception{

            final PoolDataSource  pds = PoolDataSourceFactory.getPoolDataSource();
            pds.setConnectionFactoryClassName("oracle.jdbc.replay.OracleDataSourceImpl");

            System.out.println("connection factory set");

            String URL = "jdbc:oracle:thin:@(DESCRIPTION = (TRANSPORT_CONNECT_TIMEOUT=3) (RETRY_COUNT=20)(FAILOVER=ON) " +
             " (ADDRESS = (PROTOCOL = TCP)(HOST = localhost)(PORT = 1521)) (CONNECT_DATA = " +
             " (SERVER = DEDICATED) (SERVICE_NAME=orcl)))";
            System.out.println("Using URL\n" + URL);
            pds.setURL(URL);
            pds.setUser("system");
            pds.setPassword("oracle");

            pds.setInitialPoolSize(1);
            pds.setMinPoolSize(1);
            pds.setMaxPoolSize(3);
            pds.setConnectionWaitTimeout(10);
            // RAC Features
            pds.setConnectionPoolName("Application Continuity Pool");
            pds.setFastConnectionFailoverEnabled(true);
            // use srvctl config nodeapps to get the ONS ports on the cluster
//          pds.setONSConfiguration("nodes=192.168.100.30:6200,192.168.100.32:6200");

            System.out.println("pool configured, trying to get a connection");

//          final Connection conn = null;


            final Connection conn = pds.getConnection();

            if (conn == null || !((ValidConnection) conn).isValid())  {

              System.out.println("connection is not valid");
              throw new Exception ("invalid connection obtained from the pool");
            }

            if ( conn instanceof oracle.jdbc.replay.ReplayableConnection ) {
              System.out.println("got a replay data source");
            } else {
              System.out.println("this is not a replay data source. Why not?");
            }

            System.out.println("got a connection! Getting some stats if possible");
            oracle.ucp.jdbc.JDBCConnectionPoolStatistics stats = pds.getStatistics();
            System.out.println("\tgetAvailableConnectionsCount() " + stats.getAvailableConnectionsCount());
            System.out.println("\tgetBorrowedConnectionsCount() " + stats.getBorrowedConnectionsCount() );
            System.out.println("\tgetRemainingPoolCapacityCount() " + stats.getRemainingPoolCapacityCount());
            System.out.println("\tgetTotalConnectionsCount() " + stats.getTotalConnectionsCount());

            System.out.println(((oracle.ucp.jdbc.oracle.OracleJDBCConnectionPoolStatistics)pds.getStatistics()).getFCFProcessingInfo());

            System.out.println("Now working");

            int i=0;
            while(i < 20){
                new Runnable() {
                    public void run() {                     
                        try {
                            seperateInstance(conn, pds);
                        } catch (SQLException e) {
                            e.printStackTrace();
                        }
                    }
                }.run();
                i++;
            }
    }

    private void seperateInstance(Connection conn, PoolDataSource pds) throws SQLException{
        java.sql.CallableStatement cstmt = null;
        oracle.ucp.jdbc.JDBCConnectionPoolStatistics stats = pds.getStatistics();

            conn = pds.getConnection();

            cstmt = conn.prepareCall("{call P_M_emp(?,?)}");
            cstmt.setLong(1, 1);
            cstmt.setString(2, "TEST");
            cstmt.execute();
            System.out.println("Statement executed. Now closing down");
            System.out.println("Almost done! Getting some more stats if possible");

            stats = pds.getStatistics();
            System.out.println("\tgetAvailableConnectionsCount() " + stats.getAvailableConnectionsCount());
            System.out.println("\tgetBorrowedConnectionsCount() " + stats.getBorrowedConnectionsCount() );
            System.out.println("\tgetRemainingPoolCapacityCount() " + stats.getRemainingPoolCapacityCount());
            System.out.println("\tgetTotalConnectionsCount() " + stats.getTotalConnectionsCount());

            System.out.println(((oracle.ucp.jdbc.oracle.OracleJDBCConnectionPoolStatistics)pds.getStatistics()).getFCFProcessingInfo());
            try {
                Thread.currentThread().sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("Closing connection "+ conn);
            cstmt.close();
            conn.close();
            conn = null;

    }

}

我从下面的网站获得了代码并修改了一些内容以添加线程并模拟AC。但我无法获得可重播的数据源。

https://martincarstenbach.wordpress.com/2013/12/13/playing-with-application-continuity-in-rac-12c/

1 个答案:

答案 0 :(得分:2)

要测试应用程序连续性,您可以通过执行ALTER SYSTEM KILL SESSION 'sid,serial#'来终止服务器上的会话,这将模拟失败。