db-oracle не сбрасывает данные

Я работаю над простым сервисом, используя Node.js. Он получает загруженные файлы, сохраняет их на диск и записывает некоторые метаданные в таблицу Oracle. Я использую пакет db-oracleвместе с пулом соединений, следуя этой статье: http://nodejsdb.org/2011/05/connection-pooling-node-db-with-generic -pool/

Однако я заметил, что данные, которые я вставляю, отправляются в базу данных Oracle только после того, как пул соединений закроет незанятое соединение, вызвав его метод disconnect().

Есть ли способ очистить данные перед отправкой сигнала «ОК» моему клиенту? Как это работает сейчас, сбой в моем веб-сервисе или в самом 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('');
      });
    });
  });
}

function sendError(res, err, code) {
  console.log(err);
  res.send('' + err + '', code || 500);
}

В качестве обходного пути я попытался реализовать фальшивый пул соединений и освободить все полученные соединения, но теперь мое приложение умирает с сообщением: чистый виртуальный метод callAbort 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

5
задан Fábio Batista 30 May 2012 в 20:19
поделиться