環境:Linux + oracle 10g + C
方法:多線程環境下對資料庫(Pro*C)進行檢索,使用遊標。
DBReturn ProcHandle::Test (IN string &sRuleID)
{
struct sqlca sqlca; /*define local sqlca for thread-safe */
EXEC SQL WHENEVER SQLERROR GOTO error;
EXEC SQL WHENEVER NOT FOUND GOTO notfound;
EXEC SQL CONTEXT USE :ctx[m_ctx_index];
EXEC SQL BEGIN DECLARE SECTION;
......
EXEC SQL END DECLARE SECTION;
.......
EXEC SQL
DELETE FROM Test WHERE RULEID = :s_RuleID;
EXEC SQL COMMIT;
if(sqlca.sqlcode==0)
{
rv = DB_OK;
return rv;
}
return rv;
error:
rv = sql_error();
return rv;
notfound:
EXEC SQL ROLLBACK;
return DB_NotFound;
}
我們使用多線程來對Test進行並發調用,當並發量達到10w後如果沒有 struct sqlca sqlca;這條語句就將會頻繁報錯誤。
錯誤內容如下(截取關鍵區段):
- ORA-01403: no data found
- ORA--1002: Message -1002 not found; product=RDBMS; facility=ORA
- SQL-02114: Invalid SQL Cursor usage: trying to CLOSE a CLOSEd cursor
- ORA--2114: Message -2114 not found; product=RDBMS; facility=ORA
- SQL-02114: Invalid SQL Cursor usage: trying to CLOSE a CLOSEd cursor
- SQL-02114: Invalid SQL Cursor usage: trying to CLOSE a CLOSEd cursor
- SQL-02114: Invalid SQL Cursor usage: trying to CLOSE a CLOSEd cursor
結果分析:
如果不在函數入口處重新定義sqlca,系統將使用系統全域定義的sqlca作為資料庫連接域,而這種情況下,在多任務的模式下線程是不安全的,很可能被其他線程close掉。