现在的位置: 首页 > 综合 > 正文

Pro*C 线程安全问题案例

2013年02月20日 ⁄ 综合 ⁄ 共 1088字 ⁄ 字号 评论关闭

环境: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掉。

抱歉!评论已关闭.