Estoy trabajando en un servicio simple usando Node.js. Recibe los archivos cargados, los almacena en el disco y registra algunos metadatos en una tabla de Oracle. Estoy usando el paquete db-oracle
junto con la agrupación de conexiones, siguiendo este artículo: http://nodejsdb.org/2011/05/connection-pooling-node-db-with-generic-pool/db-oracle no está lavando datos
Sin embargo, he notado que los datos que inserto solo se envían a la base de datos Oracle después de que el grupo de conexiones cierra la conexión inactiva, llamando su método disconnect()
.
¿Hay alguna forma de purgar los datos antes de enviar la señal 'OK' a mi cliente? La forma en que está funcionando ahora, un bloqueo en mi servicio web o en Oracle mismo puede causar la pérdida de datos, y el cliente de mi servicio no lo sabría. De hecho, probé esto al matar el proceso de mi aplicación después de algunas cargas y, de hecho, los datos se perdieron.
Aquí hay una versión simplificada del código:
var express = require('express');
var app = module.exports = express.createServer();
app.post('/upload', handleUpload);
app.listen(4001, function(){
console.log("Express server listening on port %d in %s mode", app.address().port, app.settings.env);
});
function handleUpload(req, res) {
res.contentType('application/xml');
var buf = '';
req.on('data', function(chunk) { buf += chunk; });
req.on('end', function() {
saveUpload(req, res, buf);
});
}
function saveUpload(req, res, buf) {
if (buf.length == 0)
return sendError(res, 'No data supplied', 422);
var payload = new Buffer(buf, 'base64');
files.save(payload, function(err, savedFile) {
if (err)
return sendError(res, 'Error while saving', 500);
var obj = { ip: req.connection.remoteAddress, location: savedFile.path,
created_at: new Date(), updated_at: new Date() };
var fields = ['IP', 'LOCATION', 'CREATED_AT', 'UPDATED_AT'];
var values = fields.map(function(v) { return obj[v.toLowerCase()] });
pool.acquire(function(err, conn) {
if (err)
return sendError(res, err, 500);
var q = conn.query().insert('FILES', fields, values);
q.execute(function(err, result) {
pool.release(conn);
if (err)
return sendError(res, err, 500);
if (result.affected < 1)
return sendError(res, 'Error saving the record', 500);
// The next statement sends the final result to the client.
// However, the new record was not yet flushed to the database.
res.end('<ok />');
});
});
});
}
function sendError(res, err, code) {
console.log(err);
res.send('<error>' + err + '</error>', code || 500);
}
Como solución, he tratado de poner en práctica un conjunto de conexiones falso y liberar todas las conexiones adquiridas, pero ahora mi aplicación está muriendo con el mensaje: pure virtual method calledAbort trap: 6
Aquí está la agrupación de conexiones falsa:
var fakePool = {
acquire: function(callback) {
new oracle.Database(config.database).connect(function(err, server) {
callback(err, this);
});
},
release: function(conn) {
conn.disconnect();
}
};
para que quede claro, no me importa el pooler falsa conexión, que era sólo una solución sucia Quiero poder vaciar los datos a Oracle antes de enviando el 'OK' a mi cliente.
Por cierto que también se abrió un billete en su Github: https://github.com/mariano/node-db-oracle/issues/38
No veo ningún commit en el código ... –
Sí, los paquetes 'db-oracle' y' node-db' no exponen ninguno, AFAIK. He profundizado en su documentación y fuentes y no he encontrado ninguna manera de realizar explícitamente una confirmación. Sin embargo, he encontrado un método 'commit' en los documentos OCCI. ¿Tal vez tendré que bifurcar el proyecto y exponer el método de compromiso? –
¿Estos paquetes quizás dependan del comportamiento de confirmación automática (ugh!)? –