摘要:設計了多線程數據庫應用系統,采用每個線程分配專用的運行上下文機制,共享連接池中的若干個物理連接,以降低資源占用、提高系統性能。實驗表明,使用連接池的系統的運行速度遠遠優于不使用連接池的運行速度。
關鍵詞:多線程;連接池;運行上下文;數據庫
0 引言
在傳統的數據庫連接方式中,每一個數據庫連接對象均對應一個物理數據庫連接,數據庫連接的建立以及關閉對系統而言是耗費系統資源的操作。在多層體系結構的應用程序環境中,這種耗費資源的動作對系統的性能影響尤為明顯。多層體系結構的應用程序通過連接池(Connection pooling)技術可以使系統的性能明顯得到提高。使用連接池意味著當應用程序需要調用一個數據庫連接時,數據庫相關的接口將返回一個重用數據庫連接來代替重新創建一個數據庫連接。通過這種方式,應用程序可以減少數據庫連接操作。特別是在多層環境中,多個客戶端可以通過共享少量的物理數據庫連接來滿足系統需求。使用連接池技術的數據庫應用程序不僅可以提高系統性能,同時也提高了系統的可測量性。
1 關鍵應用技術
1.1 PL/SQL
PL/SQL是ANSI標準SQL的Oracle版本過程化語言的擴展。它允許嵌入SQL語句,支持變量定義、過程結構以及異常處理機制等。在任何運行Oracle的平臺中都可以使用PL/SQL。C/C++語言是開發高效率數據庫應用程序的最佳語言。通過Oracle的預編譯工具Pro*C/C++,可在C/C++程序中內嵌SQL語句和PL/SQL塊。當應用程序訪問RDBMS時,每執行一條SQL語句都要經過一次網絡,通過使用PL/SQL塊,將多條SQL語句組織到同一個PL/SQL塊中,可大大降低網絡開銷,進而提高應用性能,有利于開發高性能的應用服務器。
1.2 多線程
采用多線程的交互式應用程序,提高了對用戶的響應速度。運行在現代PC機上的許多軟件包都是多線程的,為開發多線程應用提供工具。多線程的優點是能充分使用多處理器體系結構,以便每個線程能并行運行在不同的處理器上,從而獲取強大的性能。
1.3 數據庫連接池技術
連接池是指大量邏輯數據庫連接只使用了少量的物理數據庫連接。使用連接池的目的是為了提高性能,并降低資源占用。當開發多線程應用時,如果不使用連接池,那么每個線程都將使用獨立的物理連接。
2 應用方案設計
2.1 多線程應用設計
多線程應用是包含多個并發線程的數據庫應用程序,線程共享數據庫應用程序的地址空間、代碼段和數據段。對于同一進程的所有線程來說,全局變量和靜態變量是公用的,操作系統使用互斥機制管理線程對這些變量的訪問。
2.1.1 運行上下文
開發多線程數據庫應用時,為了將線程和數據庫連接有效地結合起來,Pro*C/C++提供了運行上下文(Runtime Context)。當編寫源程序時,可采用兩種方式使用運行上下文:一種是多個線程使用互斥機制共享同一個運行上下文,另一種是不同線程使用專用的運行上下文。
2.1.2 關鍵SQL語句
多線程應用程序設計需要內嵌SQL語句激活多線程支持,并用內嵌SQL語句支持運行上下文。
1.EXEC SOL ENABLE THREADS該內嵌SQL語句用于初始化支持多線程應用的進程,激活多線程支持。它是多線程應用的第一條內嵌SQL語句。
2.EXEC SQL CONTEXT ALLOCATE:var_context該內嵌語句用于初始化運行上下文變量、分配內存空間。Pro*C/C++使用偽數據類型SQL_CONTEXT定義運行上下文變量,其中變量名必須全部用大寫格式或全部用小寫格式,不能大小寫混合。
3.EXEC SOL CONTEXT USE:var_context該內嵌語句用于指定線程要使用的運行上下文。
4.EXEC SQL CONTEXT FREE:var_context該內嵌語句用于釋放運行上下文所占用的內存空間。
2.2 連接池應用
2.2.1 使用連接池特征
不使用連接池情形如圖1所示,10個線程需要分配10個物理連接,從而會占用大量服務器資源,并增加多線程應用的運行時間。

采用連接池的情形如圖2所示,多個線程共享連接池中的三個物理連接,大大降低了服務器資源的占用,并提高了應用運行性能。

2.2.2 連接池頓編譯選項
CPOOL:用于激活或禁用連接池,默認為NO。設置為YES,激活連接池特征。
CMAX:用于指定打開的最大物理連接個數,默認值為100。
CMIN:用于指定打開的最小物理連接個數,默認值為2。
CINCR:用于指定連接池每次要增加的物理連接個數,默認值為1。
cTIMEOUT:用于指定超時值,若物理連接空閑時間超出該值,則從連接池中終止該物理連接。
CNOWAIT:用于指定最大物理連接個數都處于繁忙狀態時重試物理連接的次數。
2.3 部分關鍵實現代碼
#include #include<sqlda.h> #define THREADS 20 EXEC SQL BEGIN DECLARE SECTION; typedef struct{ sql_context ctx; int threadld; )parameters; VARCHAR usemame[20],password[20].servername[20]; int empCount; EXEC SQL END DECLARE SECTION; void sqlError(struct sqlca); void Iogon(sql_context): void Iogoff(sql_context); void do_action(parameters*); SYSTEMTIME tp1,tp2; InI main() ( int i.timeTaken=0; EXEC SQL BEGIN DECLARE SECTION; sql_eontext ctx[THREADS]; HANDLE thread[THREADS]; parameters params [THREADS]: DWORD Threadld[THREADS]: EXEC SQL ENABLE THREADS; Ioginlnit(“usrname”,“pwd”,“sewer”): GetSystemTime(&tp1): for(i=0;i<THREADS;i++)( EXEC SQL CONTEXT ALLOCATE:ctx[i]: Iogon(ctx[i]); }//分配若干運行上下文,并建立連接 for(i=0;i parsms[i].cIx=ctx[i]: params[i].threadlD=i; thrsad[i]=CreateThread(NULL,0, (LPTHREAD_START_ROUTINE)do_action,params[i],0, Threadld[i]); }//創建若干線程 GetSystemTime=(&tp2): for(i=0;i if(WatiForSingleO Dject(thread[i],IINFINITE) ==WAIT_OBJECT_0)logoff(ctx[i]): EXEC SQL CONTEXT FREE:ctx[i]: }//終止所有線程 timeTaken=(tp2.wMinute-tp1.wMinute).60000; timeTaken+=(tp2.wSecond-tpl.wSecond) 1000; timeTaken+=tp2.wMilliseconds-tp1.wMUliseconds): printf(“執行時間:%fs\”,timeTaken/1000.0); retum 0: } 實驗分為兩種情形: 情形一,不使用連接池,預編譯指令為:pmc c:\\demo\est.pc threads=yes 情形二,使用連接池,預編譯指令為:proc c:\\demo\est.pcthreads=yes cpool=yes 上述二種情形運行時間分別為5.988秒和0.872秒,使用連接池的運行速度遠優于不使用連接池的速度。 3 實驗開發環境 實驗的應用開發環境是在Window XP系統下將預編譯器Pro*c/C++、Intel C++9.0編譯器集成到Visual C++6.0中。后臺數據庫采用Oracle公司的Oracle 9i數據庫管理系統。硬件環境為奔騰雙核1.6G處理器和1.5GB內存。 4 結束語 應用程序采用多線程,提高了用戶請求的響應速度。特別是高性能應用服務器的開發,能充分利用多處理器體系結構,使每個線程并行運行在不同的處理器上。采用數據庫連接池技術,則可降低系統開銷,有效地提高系統性能。