2016-07-25 13 views
1

私はpg-promiseを使用してSQLクエリを実行しています。クエリ自体は外部の.sqlファイルに保存されます。Postgresql catchトランザクションエラーとロールバック

私はトランザクションを実行すると、(予想どおり)エラーが発生した場合、Postgresはトランザクションを中止します。私が実行している問題は、トランザクションが中止された後に実行しようとする別のクエリです。このメッセージが表示されます。 "現在のトランザクションは中断され、トランザクションブロックの最後までコマンドは無視されます"。クエリーがpsqlコンソールで実行されていた場合は、失敗したクエリーの後にROLLBACKを発行することでこの問題を解決できます。アプリケーションで使用されているSQLが外部ファイルに格納されているので、これはオプションではないと思います。また、何かが失敗した場合にトランザクション全体をスローする必要があるため、セーブポイントがオプションであるとは思わない。

このエラーが発生した場合、どのようにSQLファイルをロールバックできますか?

は、ここで参考のためにSQLです:

BEGIN; 

DELETE 
FROM tournament_tossup_values 
WHERE tournament_id = $1 AND 
NOT EXISTS 
(
    SELECT id 
    FROM tournament_match 
    WHERE tournament_id = $1 
); 

UPDATE tournament 
SET bonus_point_value = $5, parts_per_bonus = $6 
WHERE id = $1 AND NOT EXISTS (
    SELECT id 
    FROM tournament_match 
    WHERE tournament_id = $1 
) 
RETURNING bonus_point_value, parts_per_bonus; <-- Any subsequent accesses to the database by the application fail if this transaction fails 

COMMIT; <-- I want to rollback everything if this fails 

は、事前にありがとうございます!

+0

あなたはライブラリを参照している。そして、あなたのDELETE操作で1とあなたのUPDATE動作と1、およびトランザクション内の2つのクエリとして、それらを実行する - そのために

、2つのファイルにあなたのSQLファイルを分割[pg-promise](https://github.com/vitaly-t/pg-promise)、あなたはトランザクションのサポートを使用していません - メソッド 'tx'?この場合、何をしているのか完全なコードを表示していないので、何が起こっているのかを確認することはできません。おそらく、すべての例に示すように、 'tx'メソッドを使用してクエリを実行するのが最善の方法です。 [Transactions](https://github.com/vitaly-t/pg-promise#transactions)を参照してください。とにかくSQLに適切な 'ROLLBACK'ロジックを提供しないので、コードをより予測可能にします。 –

答えて

1

外部SQLファイルでトランザクションを実装する場合は、COMMITROLLBACKの処理をすべて行う必要があります。そうしないと、サーバー側のコード内でトランザクションの状態が予測できなくなり、結果としてエラーが発生する可能性があります。

これはややこしいかもしれませんが、簡単に言われています。これが最善の解決策がそれを全くしない理由です。

モジュールpg-promiseは既に使用しているメソッドtxを使用して、信頼できるトランザクション処理を提供します。

db.tx(t => { 
    return t.batch([ 
     t.none('DELETE...'), 
     t.any('UPDATE...') 
    ]); 
}) 
    .then(data => { 
     // success; 
    }) 
    .catch(error => { 
     // error; 
    }); 
+0

ああ、その解決策は私が近づいてきたことです。ただ1つのSQLファイルにすべてを保存できるソリューションがないことを確認したかったのです。私は先に概説したやり方でそれを実装します。ありがとう! :) – mbhuiyan

+0

@mbhuiyan一つのファイルには解決策があるかもしれませんが、 'pg-promise'トランザクションを使うのがずっと簡単なときには、実装や使用が面倒です。 –

関連する問題