小弟刚开始接触ProC ,经验不足,使用时发现如下问题,恳请前辈指点迷津!!!先行谢过!!!
目的:
在主程序中一次性建立多个oracle连接,然后在fork的子程序中多次使用,有点象缓冲池。程序中用信号灯来保证一个连接同时只有一个子程序在用。(仅是想法,未证实是否可行,所以写了下面的测试程序进行摸索。)
问题:
小弟写了如下测试程序,这个测试程序没有更多信号灯控制,但加了sleep延时,来保证同时只有一个子程序在用这个连接。程序只执行一个select操作,耗时极短。
在运行的时候发现,如果连续fork50个以上的子进程(有延时)时,就会发生-1000错误,说是游标打开太多。
ORA-01000 maximum open cursors exceeded
Cause:
A host language program attempted to open too many cursors. The initialization parameter OPEN_CURSORS determines the maximum number of cursors per user.
Action:
Modify the program to use fewer cursors. If this error occurs often, shut down Oracle, increase the value of OPEN_CURSORS, and then restart Oracle.
子程序里我也只是执行了一个SELECT而已,还有什么地方没释放完整嘛??
我对Oracle也是新手,所以如果问的傻了,还请前辈多多批评!
现在我的测试就被卡在这里了,请教各位前辈指点一下啊!!
是不是需要在子进程里进行一些处理??
或者这样做压根不行?但在Unix ,Pro C下如何实现数据库连接缓冲池呢?
请教!!!!请各位帮忙顶一下!!谢谢!!!下面附上完整的测试程序代码:[CODE]
#include <stdio.h>
#include <stdarg.h>#define DEBUGEXEC SQL INCLUDE sqlca;
EXEC SQL INCLUDE oraca;void DebugPrt(char * fmt,...);
int ora_connect(void);
int ExecuteSql(int ID,char * atConn);EXEC SQL BEGIN DECLARE SECTION;
char Conn_Name[15];
EXEC SQL END DECLARE SECTIOn;
int main(int argc, char *argv[])
{
EXEC SQL BEGIN DECLARE SECTION;
char fid[15];
EXEC SQL END DECLARE SECTION; int pid,i,j;
int forkCount; /*建立的子进程数*/
int flagExitMain=0; /*主进程是否等待再退出*/ if (argc<2)
{
forkCount = 5;
}
else
{
forkCount = atoi(argv[1]);
}
if (forkCount<1)
{
forkCount =1 ;
}
if (argc>2)
{
flagExitMain = atoi(argv[2]);
} strcpy(Conn_Name,"conn"); /*连接名字*/
ora_connect(); /*连接数据库*/
for (i=0;i<forkCount ;i++ )
{
if (pid = fork()>0)
{
/*主进程*/
}
else if (pid ==0)
{
/*子进程*/
printf("pid=%d\n",getpid());
ExecuteSql(i,Conn_Name);
exit(0);
}
else
{
DebugPrt("fork error [%d]",pid);
}
sleep(1);
} printf("Main Proc Exit================= \n"); ora_disconnect();
exit(0);
}int ExecuteSql(int ID,char * atConn)
{
char fid[41];
DebugPrt("[%d] ",ID);
EXEC SQL AT :atConn SELECT oper_name INTO :fid FROM clerk_info \
WHERE oper_id = '999999999999999999';
if (sqlca.sqlcode<0)
{
DebugPrt("[%s]select error [%s][%d]----------------\n",atConn,fid,sqlca.sqlcode);
}
else
DebugPrt("[%s] >=[%d][%s][%d]\n",atConn,ID,fid,sqlca.sqlcode);
}int ora_connect(void)
{
EXEC SQL BEGIN DECLARE SECTION;
char username[60];
char password[20+1];
int ret;
char db_name[20];
EXEC SQL END DECLARE SECTION; strcpy(db_name,"rising"); /*数据库服务*/
strcpy(username,"fpuser"); /*用户名*/
strcpy(password,"sy"); /*密码*/ EXEC SQL CONNECT :username IDENTIFIED BY :password \
AT :Conn_Name USING :db_name;
if(sqlca.sqlcode<0)
{
DebugPrt("connect Error[%s][%d]\n",username,sqlca.sqlcode);
return(-1);
}
else
{
DebugPrt("connect OK ... [%s][%d]\n",Conn_Name,sqlca.sqlcode);
}
return(0);
}int ora_disconnect(void)
{
EXEC SQL AT :Conn_Name COMMIT WORK RELEASE;
DebugPrt("disconnect OK ... [%s][%d]\n",Conn_Name,sqlca.sqlcode);
return sqlca.sqlcode;
}
void DebugPrt(char * fmt,...)
{
#ifdef DEBUG
va_list argp;
va_start( argp, fmt );
vprintf(fmt,argp);
va_end( argp);
#endif
}[/CODE]
目的:
在主程序中一次性建立多个oracle连接,然后在fork的子程序中多次使用,有点象缓冲池。程序中用信号灯来保证一个连接同时只有一个子程序在用。(仅是想法,未证实是否可行,所以写了下面的测试程序进行摸索。)
问题:
小弟写了如下测试程序,这个测试程序没有更多信号灯控制,但加了sleep延时,来保证同时只有一个子程序在用这个连接。程序只执行一个select操作,耗时极短。
在运行的时候发现,如果连续fork50个以上的子进程(有延时)时,就会发生-1000错误,说是游标打开太多。
ORA-01000 maximum open cursors exceeded
Cause:
A host language program attempted to open too many cursors. The initialization parameter OPEN_CURSORS determines the maximum number of cursors per user.
Action:
Modify the program to use fewer cursors. If this error occurs often, shut down Oracle, increase the value of OPEN_CURSORS, and then restart Oracle.
子程序里我也只是执行了一个SELECT而已,还有什么地方没释放完整嘛??
我对Oracle也是新手,所以如果问的傻了,还请前辈多多批评!
现在我的测试就被卡在这里了,请教各位前辈指点一下啊!!
是不是需要在子进程里进行一些处理??
或者这样做压根不行?但在Unix ,Pro C下如何实现数据库连接缓冲池呢?
请教!!!!请各位帮忙顶一下!!谢谢!!!下面附上完整的测试程序代码:[CODE]
#include <stdio.h>
#include <stdarg.h>#define DEBUGEXEC SQL INCLUDE sqlca;
EXEC SQL INCLUDE oraca;void DebugPrt(char * fmt,...);
int ora_connect(void);
int ExecuteSql(int ID,char * atConn);EXEC SQL BEGIN DECLARE SECTION;
char Conn_Name[15];
EXEC SQL END DECLARE SECTIOn;
int main(int argc, char *argv[])
{
EXEC SQL BEGIN DECLARE SECTION;
char fid[15];
EXEC SQL END DECLARE SECTION; int pid,i,j;
int forkCount; /*建立的子进程数*/
int flagExitMain=0; /*主进程是否等待再退出*/ if (argc<2)
{
forkCount = 5;
}
else
{
forkCount = atoi(argv[1]);
}
if (forkCount<1)
{
forkCount =1 ;
}
if (argc>2)
{
flagExitMain = atoi(argv[2]);
} strcpy(Conn_Name,"conn"); /*连接名字*/
ora_connect(); /*连接数据库*/
for (i=0;i<forkCount ;i++ )
{
if (pid = fork()>0)
{
/*主进程*/
}
else if (pid ==0)
{
/*子进程*/
printf("pid=%d\n",getpid());
ExecuteSql(i,Conn_Name);
exit(0);
}
else
{
DebugPrt("fork error [%d]",pid);
}
sleep(1);
} printf("Main Proc Exit================= \n"); ora_disconnect();
exit(0);
}int ExecuteSql(int ID,char * atConn)
{
char fid[41];
DebugPrt("[%d] ",ID);
EXEC SQL AT :atConn SELECT oper_name INTO :fid FROM clerk_info \
WHERE oper_id = '999999999999999999';
if (sqlca.sqlcode<0)
{
DebugPrt("[%s]select error [%s][%d]----------------\n",atConn,fid,sqlca.sqlcode);
}
else
DebugPrt("[%s] >=[%d][%s][%d]\n",atConn,ID,fid,sqlca.sqlcode);
}int ora_connect(void)
{
EXEC SQL BEGIN DECLARE SECTION;
char username[60];
char password[20+1];
int ret;
char db_name[20];
EXEC SQL END DECLARE SECTION; strcpy(db_name,"rising"); /*数据库服务*/
strcpy(username,"fpuser"); /*用户名*/
strcpy(password,"sy"); /*密码*/ EXEC SQL CONNECT :username IDENTIFIED BY :password \
AT :Conn_Name USING :db_name;
if(sqlca.sqlcode<0)
{
DebugPrt("connect Error[%s][%d]\n",username,sqlca.sqlcode);
return(-1);
}
else
{
DebugPrt("connect OK ... [%s][%d]\n",Conn_Name,sqlca.sqlcode);
}
return(0);
}int ora_disconnect(void)
{
EXEC SQL AT :Conn_Name COMMIT WORK RELEASE;
DebugPrt("disconnect OK ... [%s][%d]\n",Conn_Name,sqlca.sqlcode);
return sqlca.sqlcode;
}
void DebugPrt(char * fmt,...)
{
#ifdef DEBUG
va_list argp;
va_start( argp, fmt );
vprintf(fmt,argp);
va_end( argp);
#endif
}[/CODE]
这时游标是不是该关闭了呢?另外,我用sql_context昨天也试了。也出现同样的问题。
没有关于专讲连接池的资料啊。就是ProC编程的。
{
char fid[41];
DebugPrt("[%d] ",ID);
EXEC SQL AT :atConn SELECT oper_name INTO :fid FROM clerk_info \
WHERE oper_id = '999999999999999999';
if (sqlca.sqlcode<0)
{
DebugPrt("[%s]select error [%s][%d]----------------\n",atConn,fid,sqlca.sqlcode);
}
else
DebugPrt("[%s] >=[%d][%s][%d]\n",atConn,ID,fid,sqlca.sqlcode);
}这样写游标并没有释放吧.加一句commit看看
EXEC SQL INCLUDE oraca;
EXEC ORACLE OPTION (ORACA=YES);
EXEC ORACLE OPTION (RELEASE_CURSOR=YES); /*加上这个就解决了,自动释放游标*/谢谢 ks9960啊给分了。