db-oracle不会刷新数据

我正在使用Node.js工作一个简单的服务。 它接收上传的文件,将它们存储在磁盘上,并在Oracle表上logging一些元数据。 我正在使用db-oracle软件包和连接池一起使用这篇文章: http : //nodejsdb.org/2011/05/connection-pooling-node-db-with-generic-pool/

但是,我注意到,我插入的数据只在连接池closures空闲连接之后才通过调用disconnect()方法发送到Oracle数据库。

在向客户端发送“OK”信号之前,是否有办法刷新数据? 现在它的工作方式,我的web服务或Oracle本身的崩溃可能会导致数据丢失,我的服务的客户端不会知道它。 实际上,我在一些上传之后通过杀死我的应用进程来testing,数据确实丢失了。

以下是代码的简化版本:

 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称为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(); } }; 

只是要清楚,我不关心假连接池,这只是一个肮脏的解决方法。 我希望向客户端发送“确定” 之前能够将数据清空到Oracle。

顺便说一句,我也打开了他们的Github票: https : //github.com/mariano/node-db-oracle/issues/38

你显然错过了一个事务提交。

node-db不需要公开提交API,因为在大多数RDBMS(包括Oracle)中,COMMIT是一个有效的查询。 由于包允许任意查询的执行,所以提交/回滚应该使用一个简单的execute()

代码应该改变如下:

 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) { if (err || result.affected < 1 ) { pool.release(conn); return sendError(res, err, 500); } conn.query().execute("commit", function(err,result) { if (err) { pool.release(conn); return sendError(res, err, 500); } res.end('<ok />'); pool.release(conn); }); }); }); 

这不是你的问题的确切答案,但看看node-oracle包。 它缺less连接池,但是它的commit / rollbackfunction至less可以通过代码来控制。 而且您可以随时将其与通用池解决scheme(如node-pool