Я работаю над простым сервисом, используя Node.js. Он получает загруженные файлы, сохраняет их на диске и записывает некоторые метаданные в таблице Oracle. Я использую пакет db-oracle
вместе с пулом соединений, следующий за этой статьей: http://nodejsdb.org/2011/05/connection-pooling-node-db-with-generic-pool/db-oracle не очищает данные
Однако я заметил, что данные, которые я вставляю, отправляются только в базу данных Oracle после того, как пул соединений закрывает незанятое соединение, вызывая его метод disconnect()
.
Есть ли способ сбросить данные перед отправкой сигнала «OK» моему клиенту? То, как он работает сейчас, сбой на моем веб-сервисе или на самом Oracle, может привести к потере данных, и клиент моего сервиса не будет знать об этом. Я действительно протестировал это, убив процесс моего приложения после некоторых загрузок, и данные были действительно потеряны.
Вот упрощенная версия кода:
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);
}
В качестве обходного пути, я пытался реализовать поддельные пул соединений и освободить все полученные соединения, но теперь мое приложение умирает с сообщением: pure virtual method calledAbort trap: 6
Вот поддельные пулы соединений:
var fakePool = {
acquire: function(callback) {
new oracle.Database(config.database).connect(function(err, server) {
callback(err, this);
});
},
release: function(conn) {
conn.disconnect();
}
};
Просто чтобы быть ясно, я не забочусь о поддельной связи Pooler, это было просто грязный обходной путь. Я хочу, чтобы вы могли очистить данные до Oracle до, отправив «OK» моему клиенту.
Btw Я также открыл билет на их Github: https://github.com/mariano/node-db-oracle/issues/38
Я не вижу никакой фиксации в код ... –
Да, пакеты 'db-oracle' и' node-db' не выставляются, AFAIK. Я углубился в их документацию и источники и не нашел способа явно выполнить фиксацию. Однако я нашел метод «commit» в документах OCCI. Может быть, мне придется разветвить проект и разоблачить метод фиксации? –
Возможно ли, чтобы эти пакеты зависели от (автоответчика) поведения? –