DRCP die Zweite

Nach meinem letzten gescheiterten Versuch das neue Connection Pooling Feature von Oracle 11g zu testen, habe ich mich ein wenig tiefer an die Basis herangewagt und OCCI für weitere Tests bemüht. Der Testverlauf ist recht simpel gehalten:

  1. Oracle Umgebung initialisieren
  2. Zeit merken
  3. 1000 mal
    1. Verbindung zur Datenbank aufbauen
    2. SELECT SYSDATE FROM DUAL
    3. Verbindung schliessen
  4. Zeit messen und Differenz errechnen

Verglichen wird der Verbindungsaufbau einer “normalen” Verbindung mittels oracle::occi::Environment::createConnection() und oracle::occi::StatelessConnectionPool::getConnection(). Der Sourcecode ist – ähnlich wie die Beschreibung des Testverlaufs – recht kurz gehalten:

using namespace std;
using namespace oracle::occi;

int _tmain(int argc, _TCHAR* argv[])
{
    string username  = "test";
    string password  = username;
    string db_normal = "oradev";
    string db_pool   = "oradev_pool";

    //Variablen zur Zeitmessung
    LONGLONG mFreq, mCurrent, mLast;

    Environment* env =
        Environment::createEnvironment (Environment::DEFAULT);
    StatelessConnectionPool* pool =
        env->createStatelessConnectionPool(username, password, db_pool);

    //Frequenz holen
    if (!QueryPerformanceFrequency((LARGE_INTEGER*)&mFreq))
        return -1;
    //1. Messung
    QueryPerformanceCounter((LARGE_INTEGER*)&mCurrent);

    for (int i=1; i<=1000; i++)
    {

        #ifdef POOLING
            Connection* conn =
                pool->getConnection("test", Connection::Purity::SELF);
        #else
            Connection* conn =
                env->createConnection(username, password, db_normal);
        #endif

        Statement* stmt =
            conn->createStatement("SELECT SYSDATE FROM DUAL");
        ResultSet* res = stmt->executeQuery();

        while (res->next())
        {
            oracle::occi::Date d = res->getDate(1);
        }

        stmt->closeResultSet(res);
        conn->terminateStatement(stmt);

        #ifdef POOLING
            pool->releaseConnection(conn);

        #else
            env->terminateConnection(conn);
        #endif
    }

    //2. Messung
    QueryPerformanceCounter((LARGE_INTEGER*)&amp;amp;mLast);

    // Ausgabe Zeitunterschied
    double dTimeDiff = (((double)(mLast-mCurrent))/((double)mFreq));
    std::cout << "Zeit: " << dTimeDiff << std::endl; 

    env->terminateStatelessConnectionPool(pool);
    Environment::terminateEnvironment(env);

    return 0;
}

Das Ergebnis ist erfreulich, wenn auch nicht sonderlich überraschend: Während der normale Verbindungsaufbau über createConnection bei 1000 Durchläufen ca. 28 Sekunden dauert, so geht es mit getConnection in weniger als einer Sekunde (~0,21 sec) . Ein Blick auf die View V$CPOOL_CC_STATS beweist, dass der Connection Pool genutzt wurde, und das zudem äußerst effektiv.

SYSTEM @oradev_pool> select NUM_REQUESTS, NUM_HITS, NUM_MISSES from V$CPOOL_CC_STATS;

NUM_REQUESTS    NUM_HITS        NUM_MISSES
--------------- --------------- ---------------
1000            999             0

Schlagworte: , , , ,

Kommentieren