2016-05-05 6 views
2

NodeJS/Postgresを使用してデータベースに3つの挿入を行う必要がある単純なWebアプリケーションを構築しています。NodeJSとPostgresを使用したトランザクションチェーン内のオプションのINSERTステートメント

私はpg-transactionを使用しているステートメントのチェーンを制御します。

私の問題は、常に2番目のINSERTを実行する必要がありますが、3番目のINSERTを実行する条件があることです。

多分、私のコードをより良い方法でビルドすることができます(提案は大歓迎です)。各クエリの後(ERR){}場合は三回同じを繰り返すように醜いと思わ

function(req, res) { 
 
    var tx = new Transaction(client); 
 
    tx.on('error', die); 
 
    tx.begin(); 
 
    
 
    tx.query('INSERT_1 VALUES(...) RETURNING id', paramValues, function(err, result) { 
 
    if (err) { 
 
     tx.rollback(); 
 
     res.send("Something was wrong!"); 
 
     return; 
 
    } 
 
    
 
    var paramValues2 = result.rows[0].id; 
 
    tx.query('INSERT_2 VALUES(...)', paramValues2, function(err2, result2) { 
 
     if (err) { 
 
     tx.rollback(); 
 
     res.send("Something was wrong!"); 
 
     return; 
 
     } 
 
     
 
     // HERE'S THE PROBLEM (I don't want to run it always this last statement) 
 
     // If I don't run it, I will miss tx.commit() 
 
     if (req.body.value != null) { 
 
     tx.query('INSERT_3 VALUES(...)', paramValues3, function(err3, result3) { 
 
      if (err) { 
 
      tx.rollback(); 
 
      res.send("Something was wrong!"); 
 
      return; 
 
      } 
 
     
 
      tx.commit(); 
 
      res.send("Everything fine!"); 
 
     }); 
 
     } 
 
    }); 
 
    }); 
 
}

:ここ

は擬似コードです。

私が見つけたいくつかのオプションを確認しようとしましたを続行しましたが、この問題を解決する方法が見当たりませんでした。

ご提案は大歓迎です!

ありがとうございます!

+0

あなたが最後の挿入にそれがあることを確認しています'' INSERT_3 VALUES(...) '、paramValues2'ではなく、 '' INSERT_3 VALUES(...)' '、paramValues3'の中のいくつかではありませんか?つまり、最初のクエリの結果を使用して最後のクエリを実行する必要がありますか? –

答えて

3

手動トランザクション管理は危険な道のりであり、それから遠ざかるようにしてください! ;)ここで

pg-promiseの助けを借りて、それを正しく行うには方法は次のとおりです。

function(req, res) { 
    db.tx(t => { // automatic BEGIN 
      return t.one('INSERT_1 VALUES(...) RETURNING id', paramValues) 
       .then(data => { 
        var q = t.none('INSERT_2 VALUES(...)', data.id); 
        if (req.body.value != null) { 
         return q.then(()=> t.none('INSERT_3 VALUES(...)', data.id)); 
        } 
        return q; 
       }); 
     }) 
     .then(data => { 
      res.send("Everything's fine!"); // automatic COMMIT was executed 
     }) 
     .catch(error => { 
      res.send("Something is wrong!"); // automatic ROLLBACK was executed 
     }); 
} 

それとも、あなたはES6ジェネレータを好む場合:

function (req, res) { 
    db.tx(function * (t) { // automatic BEGIN 
      let data = yield t.one('INSERT_1 VALUES(...) RETURNING id', paramValues); 
      let q = yield t.none('INSERT_2 VALUES(...)', data.id); 
      if (req.body.value != null) { 
       return yield t.none('INSERT_3 VALUES(...)', data.id); 
      } 
      return q; 
     }) 
     .then(data => { 
      res.send("Everything's fine!"); // automatic COMMIT was executed 
     }) 
     .catch(error => { 
      res.send("Something is wrong!"); // automatic ROLLBACK was executed 
     }); 
} 
+1

まさに私が必要としたもの。ちょうどテストされ、それは完全に動作します。あなたの完全な答えをありがとう! – Tom

関連する問題