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:
- Oracle Umgebung initialisieren
- Zeit merken
- 1000 mal
- Verbindung zur Datenbank aufbauen
- SELECT SYSDATE FROM DUAL
- Verbindung schliessen
- 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;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