postgresのクライアントでSQLを実行した際、突然クエリを正しく入力したにもかかわらず、実行できなくなったことがある。
結構ハマったので、このエラーについてまとめておく。
Postgres
のTransaction
内に一度エラーが発生すると、明示的にそのTransaction
をabort
しなければならないのだ。
因みに、SQL Server
等の他のRDBMSだと、エラーが出てきても、その場でクエリを見直しして、処理を続けるんだね。
[例]
begin;
selet
* from foo; -- わざとseletにした
このクエリを実行すると、「ERROR: syntax error at or near ‘selet’“」
が出るはず。
これで気づいてselect * from foo;
の正しいクエリに修正して、再度実行すると、冒頭のエラーが出ることがわかる。
rollback;
を一度実行してから、最初からトランザクションを実行しなければならない。
Postgres
はそうなったのか?Postgres
はユーザで終了したTransaction
とシステムの都合(例外等)で終了したTransaction
は区別しているようだ。
https://github.com/postgres/postgres/blob/master/src/backend/access/transam/README
を参照すると、
Transaction
が終了した場合:AbortCurrentTransaction アプリケーション状態はTBLOCK_ABORTTransaction
を終了した場合:UserAbortTransactionBlock アプリケーション状態はTBLOCK_ABORT_ENDケース1でも自動にTransaction
を終了させれば良いでしょうかって思うよね。
実はそれに応じるonerrorrollback
オプションがあるが、やっぱり長いTransaction
内にエラーが発生したら、最初から実施しないといけない点は不便が感じるよね〜
onerrorrollback
についての詳細説明も是非ご参照ください。
https://www.endpoint.com/blog/2015/02/24/postgres-onerrorrollback-explained