在项目开发过程中,遇到过这样的问题:
代码中,需要访问两个数据库(定为数据库A,和数据库B)。在从数据库A切换到数据库B的时候,要释放A所有申请的资源。
由于模型设计原因,在申请句柄时,在不同的地方申请了2个 错误 句柄。
在释放时,执行了如下语句:
if (srvhpt!=NULL)
(void) OCIHandleFree((dvoid *) srvhpt, (ub4) OCI_HTYPE_SERVER);
if (svchpt!=NULL)
(void) OCIHandleFree((dvoid *) svchpt, (ub4) OCI_HTYPE_SVCCTX);
if (errhpt!=NULL)
(void) OCIHandleFree((dvoid *) errhpt, (ub4) OCI_HTYPE_ERROR); --OCI错误句柄
if (authpt!=NULL)
(void) OCIHandleFree((dvoid *) authpt, (ub4) OCI_HTYPE_SESSION);
if (envhpt!=NULL)
(void) OCIHandleFree((dvoid *) envhpt, (ub4) OCI_HTYPE_ENV); --OCI环境句柄
上述语句只释放了 其中的1个错误句柄。
在此之后,再次释放(或其他操作)程序申请的另一个错误句柄时,出现了core文件:
0x0000003c2be091c0 in pthread_mutex_lock () from /lib64/libpthread.so.0
#1 0x00007f71caafb98d in sltsmna () from /home/oracle/product/db1/lib/libclntsh.so.10.1
#2 0x00007f71ca03e667 in kpufhndl0 () from /home/oracle/product/db1/lib/libclntsh.so.10.1
#3 0x00007f71ca03d3e9 in kpufhndl () from /home/oracle/product/db1/lib/libclntsh.so.10.1
#4 0x00007f71ca135ed5 in OCIHandleFree () from /home/oracle/product/db1/lib/libclntsh.so.10.1
经研究发现:在句柄分配时,OCIHandleAlloc()函数,都是针对某一个 环境句柄(父句柄)而分配的;
由此考虑到:在释放OCI环境句柄之前,将另一个错误句柄释放掉!
这样修改之后,程序不再出现core文件了。
由此可推断:
OCI函数需要按照特定的顺序执行,即 在分配句柄之前,要 创建OCI环境句柄;
在释放句柄时,也要 先释放其他句柄,最后再释放 OCI环境句柄。