Oracle Pro*C 多線程編程的核心挑戰在於運行時上下文隔離與共享連接池管理。本文解析一個生產級多線程導出程序,重點講解 sql_context、THREADS 模式、游標預取優化。
struct paramater {
sql_context stx; // 線程專屬 SQL 上下文
char table[17];
char fileName[17];
};
每線程獨立 sql_context 實現連接級隔離,避免共享 sqlca 衝突。
EXEC SQL ENABLE THREADS; // 必須在首次 CONTEXT ALLOCATE 前調用 EXEC SQL CONTEXT ALLOCATE :ctx[i]; // 分配線程上下文 // ... 使用 ctx[i] ... EXEC SQL CONTEXT FREE :ctx[i]; // 釋放
ENABLE THREADS 告訴預編譯器生成線程安全代碼sql_context,內含連接、游標、sqlca 狀態EXEC SQL CONTEXT USE :ctx; // 後續 SQL 語句綁定此上下文 EXEC SQL CONNECT ...; EXEC SQL DECLARE cur CURSOR ...;
編譯器將展開為運行時上下文切換調用,確保多線程安全。
EXEC ORACLE OPTION (PREFETCH=65535); // 開啟大額預取
EXEC SQL OPEN cur;
for (;;) {
EXEC SQL FOR :this_count FETCH cur INTO :str;
// 批量處理...
}
EXEC ORACLE OPTION (PREFETCH=1); // 恢復默認
FOR :n FETCH 數組接收EXEC SQL FOR :this_count FETCH cur INTO :str; this_count = sqlca.sqlerrd[2] - row_begin; row_begin = sqlca.sqlerrd[2];
sqlca.sqlerrd[2] 累積已提取行數FOR 子句實現高吞吐批量提取EXEC SQL WHENEVER SQLERROR CONTINUE; // 避免錯誤觸發長跳轉
// ... 操作 ...
if (sqlca.sqlcode != 0) { /* 記錄錯誤 */ }
EXEC SQL CLOSE cur;
EXEC SQL COMMIT WORK RELEASE;
EXEC SQL CONTEXT FREE :ctx;
int main() {
sql_context ctx[2];
struct paramater pa[2];
pthread_t pt[2];
for (int i = 0; i < 2; i++) {
EXEC SQL ENABLE THREADS;
EXEC SQL CONTEXT ALLOCATE :ctx[i];
connectDB("bill", "bill", "hntestbl", ctx[i]);
sprintf(pa[i].table, "T_CI_USERINFO_B");
sprintf(pa[i].fileName, "ttttt%d", i+1);
pa[i].stx = ctx[i];
pthread_create(&pt[i], NULL, exportTable, &pa[i]);
}
for (int j = 0; j < 2; j++) {
pthread_join(pt[j], NULL);
closeDB(ctx[j]);
EXEC SQL CONTEXT FREE :ctx[j];
}
return 0;
}
新項目建議考慮:
Pro*C 多線程核心在於 sql_context 隔離 + CONTEXT USE 切換 + PREFETCH 批量 + 數組 FETCH。掌握這四大支柱,即可構建高性能、線程安全的數據庫交互程序。雖然 Pro*C 屬於上一代技術,但在存量核心系統維護中仍具不可替代價值。