0

我创建了一个异步 ExecuteQuery 函数,该函数能够异步执行查询,因此如果在循环中调用它,下一个查询会等待前一个查询完成后再执行。doCreatePool 函数在程序初始化时被调用一次。它创建一个连接池并将其保存在全局变量 config.Oracle_POOL 中,以便连接池保持活动状态,即使在 doCreatePool 返回之后也是如此。

Socket.io 事件调用 ExecuteQuery来执行查询(循环中的一个或多个)。

一切正常,但在执行一定数量的查询后,我收到 ORA-1000 错误:“错误:ORA-01000:超出最大打开游标”,无论是选择、更新和插入查询。

通常 Connexion 池应该避免这个问题?

我的代码有什么问题?

doCreatePool (); //Create a connexion pool and save it in config.Oracle_POOL
//dbConfig={....}

function doCreatePool () {
    dbConfig=config.Settings.DataBaseConnexionString;
    oracle.createPool (
      {
        user          : dbConfig.user,
        password      : dbConfig.password,
        connectString : dbConfig.connectString,
        poolMax       : 44,
        poolMin       : 2,
        poolIncrement : 5,
        poolTimeout   : 4
      },
      function(err, pool)
      {
        if (err) {
          console.error("createPool() callback: " + err.message);
          return;
        } else {
            config.Oracle_POOL = pool;
        }
     });      
}

function ExecuteQuery(Query, LstParam, callBack) {

    config.Oracle_POOL.getConnection( function(err, connection) {
        if (err){ 
            console.log("Oracle connexion pool --> err --> ", err);
            if (connection)
            connection.release(
                function(err) {
                    if (err) {
                        console.log("(1) connection.release --> err--> ",err)
                    }
                }
            );  
            callBack(err, { rows : [] });   
        } else {
            var OracleQueryOptions={outFormat: oracle.OBJECT, maxRows : 500, autoCommit : true};
            connection.execute(Query, LstParam, OracleQueryOptions , function(err, results) {
                if (!err) {
                    console.log("* connection.execute  --> err--> ",err, "Query --> ", Query);
                }
                connection.release( function(err2) {                            
                        if (err2) {
                            console.log("(2) connection.release --> err-->",err)
                        }
                        callBack(err, results);
                    }
                );
            });
        }
    });     
            
        
}
4

1 回答 1

0

我知道我的问题来自哪里。通过在调用 getConnexion() 函数之前添加这些代码行

// NUMBER OF CONNCETIONS OPEN
console.log("B4getConnexion -> ORACLE: CONNX OPEN: " + config.Oracle_POOL.connectionsOpen);

// NUMBER OF CONNEXTIONS IN USE
console.log("B4getConnexion -> ORACLE: CONNX IN USE: " + config.Oracle_POOL.connectionsInUse);

这在 getConnexion() 函数调用结束时:

// NUMBER OF CONNCETIONS OPEN
console.log("AFTER/getConnexion -> ORACLE: CONNX OPEN: " + config.Oracle_POOL.connectionsOpen);

// NUMBER OF CONNEXTIONS IN USE
console.log("AFTER/getConnexion -> ORACLE: CONNX IN USE: " + config.Oracle_POOL.connectionsInUse);

我注意到config.Oracle_POOL.connectionsOpen 会增加,直到达到 poolMax (44)。这就是为什么我会犯错误的原因(这是我现在的看法):

ORA-24418: Cannot open further sessions
ORA-24418: Cannot open further sessions
ORA-01000: maximum open cursors exceeded

如何避免 config.Oracle_POOL.connectionsOpen 增加?请注意,console.log 通知 RelaseConnexion 在 ExecuteQuery 和 getConnexion 之后成功调用。所有序列都按顺序执行。

如果我不使用释放连接(这意味着通过在循环中执行多个语句)config.Oracle_POOL.connections 保持稳定。 但在循环结束时,我从句连接,当事件发生时,它开始一个新循环,我创建一个新的连接,然后 config.Oracle_POOL.connections 增加......

于 2015-06-06T10:14:42.530 回答