重点:"Oracle仅在将会话释放回池中时检查超时会话。"
============================================================
之前c++走MS ADO调用oracle,单线程1秒才能跑100次存储过程,我要落tick行情,效率上不满足业务要求;用多线程么,MS ADO并非线程安全,面临crash的风险;痛定思痛,决定啃一下硬骨头,使用OCCI,发现不少坑,为造福广大同胞,留下笔记。
要做就做到完美,光会写单connection不行,我们来尝试下更高效的connectionPool,以节约建立、销毁连接的时间。
问题来了,根据这位同学的提问,连接池中的连接,长时间不用就有超时的风险(废连接):https://bbs.csdn.net/topics/390328012/
根据在oracle茫茫文档中的捞针,好像发现了问题(oracle官方文档链接:https://docs.oracle.com/en/database/oracle/oracle-database/20/lncpp/connectionpool-class.html)
在oracle中,在客户端侧,使用occi,无论是【连接池】还是【无状态连接池】,对每个连接,都有超时设置。
void setTimeOut(
unsigned int connTimeOut = 0)=0;
在oracle中,在服务端侧,对每个连接有默认的超时时间。
如果,客户端侧不设置(且闲置时间久),可能被动的被服务器端超时中断,就会收到失败代码ORA-03114。
又如果,客户端侧将超时值设置值过大,以至于大于服务器段的设置,也会被服务器端中断,下次使用连接,会出现同样失败。
oracle官方文档里写:
Sets the time out period for a connection in the connection pool. OCCI terminates any connections related to this connection pool that have been idle for longer than the time out period specified.
//设置连接池中连接的超时时间。OCCI会终止与该连接池有关的所有空闲时间超过指定的超时时间的连接。
If this attribute is not set, the least recently used sessions are timed out when pool space is required. Oracle only checks for timed out sessions when it releases a session back to the pool.
//如果未设置此属性,则在需要池空间时,最近最少使用的会话将超时。Oracle仅在将会话释放回池中时检查超时会话。
"Oracle仅在将会话释放回池中时检查超时会话。" 哇,原来当调用getConnection时,也可能拿到的是失效的连接。
解决办法,
1、设置超时时间短一些,短于服务器侧的设置,使OCCI可以主动维护
2、try catch,当抛出ORA-03114,调用terminateConnection, 并重新getconnection,递归至连接有效
若有帮助请留下您的点赞~