我遇到了Oracle DB模块的问题: https://github.com/oracle/node-oracledb/blob/master/doc/api.md
我的应用程序每小时有300到900次点击(通常来自大约100个用户)。该应用程序在后台有许多$ .post请求,用于从数据库中检索信息并显示给用户。
我最近切换到此模块,因为它是Oracle自己的(之前我使用的是https://github.com/joeferner/node-oracle)。
以下是我如何制定的:
/ bin中/万维网
oracledb.createPool(
{
user : 'USER'
password : 'PASS',
connectString : 'DB:1521/SID:POOLED',
connectionClass : 'ARBITRARY_NAME',
poolMin : 1,
poolMax : 50,
poolTimeout : 300
},
function(err, pool)
{
if (err) {
console.log(err);
}
require('../libs/db')(pool); // Export pool to separate file
}
)
/libs/db.js
module.exports = function(pool) {
// Require oracle module for formatting
var oracledb = require('oracledb');
// Export acquire and query function
module.exports.acquire_and_query = function(sql, params, callback){
// ACQUIRE connection from pool
pool.getConnection(function(err, connection){
// NUMBER OF CONNCETIONS OPEN
console.log("ORACLE: CONNX OPEN: " + pool.connectionsOpen);
// NUMBER OF CONNEXTIONS IN USE
console.log("ORACLE: CONNX IN USE: " + pool.connectionsInUse);
if (err) {
console.log(err.message);
return;
}
// Use connection to QUERY db and return JSON object
connection.execute(sql, params, {maxRows: 1000, isAutoCommit: true, outFormat: oracledb.OBJECT}, function(err, result){
// Error Handling
if (err) {
console.log(err.message); // Log the error
return false; // Return false for our error handling
}
// Release the connection back to the pool
connection.release(function(err) {
if (err) {
console.log(err.message);
return;
}
})
// Return callback with rowset first, out bind paramaters second
return callback(result.rows, result.outBinds, result.rowsAffected);
})
})
}
}
此模块" acquire_and_query"在我们的应用程序中调用,并且有SQL并且它的参数被传入以执行。
Oracle数据库允许的最大池化连接数设置为80(我们不会超过它们) - 通常看起来很开心。
然而,节点应用程序不断抛出ORA-24418:无法打开更多会话,我不确定如何解决此问题。
感谢。
答案 0 :(得分:4)
已解决 - 问题:我的编码很差!
我无意中设置了一个Socket.IO事件来更新EVERYONE多次连接的视图(而不是一次查询数据库,然后通过套接字发送视图......)叹息
我甚至更愚蠢地在基于事务的查询中使用for循环(在每次运行时都插入了多个数据)......一旦我将其更改为递归模式 - 它就开始游动了!
这里有关于循环和递归模式的好文章:http://www.richardrodger.com/2011/04/21/node-js-how-to-write-a-for-loop-with-callbacks/#.VaQjJJNViko
无论如何 - 这就是我现在使用的(它运作得相当好) 使用node-oracledb v0.6(https://github.com/oracle/node-oracledb)和Express 4(http://expressjs.com/)
<强>仓/万维网强>
/**
* Database
*/
// AS PER DOCUMENTATION: https://github.com/oracle/node-oracledb/blob/master/examples/dbconfig.js
var dbconfig = require("../libs/dbconfig.js");
oracledb.connectionClass = dbconfig.connectionClass,
oracledb.createPool({
user: dbconfig.user,
password: dbconfig.password,
connectString: dbconfig.connectString,
poolMax: 44,
poolMin: 2,
poolIncrement: 5,
poolTimeout: 4
}, function(err, pool) {
if (err) {
console.log("ERROR: ", new Date(), ": createPool() callback: " + err.message);
return;
}
require('../libs/oracledb.js')(pool);
});
<强>库/ oracledb.js 强>
module.exports = function(pool) {
////////////////////////////
// INSTANTIATE THE DRIVER //
////////////////////////////
var oracledb = require("oracledb");
//////////////////////
// GET A CONNECTION //
//////////////////////
var doConnect = function(callback) {
console.log("INFO: Module getConnection() called - attempting to retrieve a connection using the node-oracledb driver");
pool.getConnection(function(err, connection) {
// UNABLE TO GET CONNECTION - CALLBACK WITH ERROR
if (err) {
console.log("ERROR: Cannot get a connection: ", err);
return callback(err);
}
// If pool is defined - show connectionsOpen and connectionsInUse
if (typeof pool !== "undefined") {
console.log("INFO: Connections open: " + pool.connectionsOpen);
console.log("INFO: Connections in use: " + pool.connectionsInUse);
}
// Else everything looks good
// Obtain the Oracle Session ID, then return the connection
doExecute(connection, "SELECT SYS_CONTEXT('userenv', 'sid') AS session_id FROM DUAL", {}, function(err, result) {
// Something went wrong, releae the connection and return the error
if (err) {
console.log("ERROR: Unable to determine Oracle SESSION ID for this transaction: ", err);
releaseConnection(connection);
return callback(err);
}
// Log the connection ID (we do this to ensure the conncetions are being pooled correctly)
console.log("INFO: Connection retrieved from the database, SESSION ID: ", result.rows[0]['SESSION_ID']);
// Return the connection for use in model
return callback(err, connection);
});
});
}
/////////////
// EXECUTE //
/////////////
var doExecute = function(connection, sql, params, callback) {
connection.execute(sql, params, { autoCommit: false, outFormat: oracledb.OBJECT, maxRows:1000 }, function(err, result) {
// Something went wrong - handle the data and release the connection
if (err) {
console.log("ERROR: Unable to execute the SQL: ", err);
//releaseConnection(connection);
return callback(err);
}
// Return the result to the request initiator
// console.log("INFO: Result from Database: ", result)
return callback(err, result);
});
}
////////////
// COMMIT //
////////////
var doCommit = function(connection, callback) {
connection.commit(function(err) {
if (err) {
console.log("ERROR: Unable to COMMIT transaction: ", err);
}
return callback(err, connection);
});
}
//////////////
// ROLLBACK //
//////////////
var doRollback = function(connection, callback) {
connection.rollback(function(err) {
if (err) {
console.log("ERROR: Unable to ROLLBACK transaction: ", err);
}
return callback(err, connection);
});
}
//////////////////////////
// RELEASE A CONNECTION //
//////////////////////////
var doRelease = function(connection) {
connection.release(function(err) {
if (err) {
console.log("ERROR: Unable to RELEASE the connection: ", err);
}
return;
});
}
//////////////////////////////
// EXPORT THE FUNCTIONALITY //
//////////////////////////////
module.exports.doConnect = doConnect;
module.exports.doExecute = doExecute;
module.exports.doCommit = doCommit;
module.exports.doRollback = doRollback;
module.exports.doRelease = doRelease;
}
使用示例
//////////////////////////////
// REQUIRE RELEVANT MODULES //
//////////////////////////////
var db = require("../libs/oracledb.js");
var oracledb = require('oracledb');
var sql = "";
///////////////////////////
// RETRIEVE CURRENT DATE //
///////////////////////////
module.exports.getCurDate = function(callback) {
sql = "SELECT CURRENT_DATE FROM DUAL";
db.doConnect(function(err, connection){
console.log("INFO: Database - Retrieving CURRENT_DATE FROM DUAL");
if (err) {
console.log("ERROR: Unable to get a connection ");
return callback(err);
} else {
db.doExecute(
connection, sql
, {} // PASS BIND PARAMS IN HERE - SEE ORACLEDB DOCS
, function(err, result) {
if (err) {
db.doRelease(connection); // RELEASE CONNECTION
return callback(err); // ERROR
} else {
db.doRelease(connection); // RELEASE CONNECTION
return callback(err, result.rows); // ALL IS GOOD
}
}
);
}
});
}
答案 1 :(得分:1)
当达到OCISessionPoolCreate中提供的sessMax参数时,将引发此错误消息。
因此,我的第一步是验证数据库会话是否正确关闭。
出现此错误消息时,请执行以下三个操作:
1.-(使用sqlplus)show parameter sess
2.-(使用sqlplus) 从v $ session中选择用户名,机器,程序,计数(*) 按用户名,机器,程序分组 按顺序排列;
3.-如果在此活动期间有任何其他ORA消息,请在alert.log中验证。
你执行了这个步骤吗? (分享你的结果)