- PR -

PostgreSQL 8.0 トランザクションを手動でロールバックする方法

投稿者投稿内容
上総
大ベテラン
会議室デビュー日: 2006/06/22
投稿数: 107
投稿日時: 2007-10-25 00:13
実現可能かは判りませんが、サーバー側でlibpqを使用してプロセスIDを返す関数を
作成し、PostgrSQLに組み込んでその値を取得後に画面上にでもプロセスIDを表示し、
その後実際のSQLを流したらどうでしょうか?

そうすればWebアプリが落ちる前にプロセスIDが判っていれば、Webアプリが落ちた後に
そのプロセスIDをサーバー側で落とせば良いかと思います。

プログラムの手間及びテストの手間を考慮すれば、テストを行う人の数だけユーザーを
作成し、Webアプリが落ちた場合はpgAdminIIIからユーザーからPIDを判別し、サーバー
側でプロセスを落とせば良いかと思います。
(pgAdminIIIを繋ぎ、データベースの統計情報から、接続されているユーザーは判別
可能かと・・・)
カーニー
ぬし
会議室デビュー日: 2003/09/04
投稿数: 358
お住まい・勤務地: 東京
投稿日時: 2007-10-25 10:27
ところで、そのWebアプリケーションは、どうやってPostgreSQLへのConnectionを取得し、最後にクローズするのですか?
ロックが残るくらいですからコネクションプールを使っているのかと想像しますし、お話からすると、その辺りも暫定モジュールを使っているような気がしますが、単にクローズの直前でConnection.rollback()しとけばいいんじゃないかと思ってしまいます。

あと、例外のcatchは禁止されているということですが、こういうのもダメ?

コード:
  try {
    ...
  } catch (Exception e) {
    ...
    throw e;
  }



呼び出し元は例外の発生を検知できますが。

それにしてもPostgreSQLの面倒なところは、トランザクション中にエラーが発生したら、ROLLBACKコマンドを発行する以外の選択肢がないところですね。エラーを無視して別の処理を行うということができんのです。ROLLBACK以外のコマンドを発行すると「いったんロールバックしろ」というエラーが返ってくるのです。
かつのり
ぬし
会議室デビュー日: 2004/03/18
投稿数: 2015
お住まい・勤務地: 札幌
投稿日時: 2007-10-25 12:26
暫定モジュールを使っているのは理解できましたが、
暫定モジュールでよいのであれば、
例えばSpring+AOPで宣言トランザクションを暫定的に利用すると、
XX例外でロールバック、XX例外でコミットと、
細かいテストも苦労なく出来ますよ。

他にもConnectionのプロキシを作成して、
トランザクション開始から数分で自動ロールバックするとか、
色々と対策はあります。

本当にPostgreSQLの接続を捕まえて、
外部から操作する必要があるのか正直疑問です。
take11
会議室デビュー日: 2006/02/16
投稿数: 18
投稿日時: 2007-10-29 12:34
みなさん、ありがとうございました。
自分の未熟さが非常によく理解できました。
みなさんくらいのレベルに達しないと、DBを使ったプログラミングは
してはいけませんね。そういう意味では、SQL文を作るまでしか
許さないという方針は確かに正解だなーと改めて思います。

>上総さん

> 実現可能かは判りませんが、サーバー側でlibpqを使用してプロセスIDを返す関数を
> 作成し、PostgrSQLに組み込んでその値を取得後に画面上にでもプロセスIDを表示し、
> その後実際のSQLを流したらどうでしょうか?

 少なくとも今現在の私には実現不可能なのはわかります。(^^;
 ただ、そのような方法があるということがわかったのはとても収穫でした。
ちょっと詳しい人に相談してみます。
take11
会議室デビュー日: 2006/02/16
投稿数: 18
投稿日時: 2007-10-29 12:44
>カーニーさん

 いろいろ検討したんですが、やっぱりcatchしてthrowかなー、という結論に
達しつつあります。
 実は本当は最初からそうしようかという話があったのですが、そもそもDB管理モジュール
ができてしまえば必要がなくなる部分ですし、なんだかんだでコーディング量も
けっこうありそうなので、変なロックが残ったらそのたび削除できれば
その方が楽か、と思っていたのですが、どうもそうでもなさそうな気も
してきましたので……

> 単にクローズの直前でConnection.rollback()しとけばいいんじゃないかと思ってしまいます。

 そうなのかもしれないです。暫定モジュールを作った人に相談してみます。

> それにしてもPostgreSQLの面倒なところは、トランザクション中にエラーが発生したら、ROLLBACKコマンドを発行する以外の選択肢がないところですね。

 そうですね。今回初めて使ってみて、確かに、フリーにしてはすごいなあ……、と
思わせる部分は多々あるのですが、こういう痒いところといいますか、そういう
部分は、しかたないとはいえちょっと面倒だなあ、とは思いました。


 ありがとうございました。
take11
会議室デビュー日: 2006/02/16
投稿数: 18
投稿日時: 2007-10-29 12:50
>かつのりさん

> 暫定モジュールを使っているのは理解できましたが、
> 暫定モジュールでよいのであれば、
> 例えばSpring+AOPで宣言トランザクションを暫定的に利用すると、
> XX例外でロールバック、XX例外でコミットと、
> 細かいテストも苦労なく出来ますよ。
>
> 他にもConnectionのプロキシを作成して、
> トランザクション開始から数分で自動ロールバックするとか、
> 色々と対策はあります。

 うーん、なるほど。すごいですね。誰も全く思いつかなかった
(or知らなかった)方法ばかりです。ちょっと調べてみます。

> 本当にPostgreSQLの接続を捕まえて、
> 外部から操作する必要があるのか正直疑問です。

 いや、なんといいますか、「いろいろ正当な方法はあるだろうけど、
テストの間だけだし、変なロックが残ったら外部から戻しちゃうのが
一番簡単なんじゃ?」というふうに思っていたのです。
 でもどうやらそうでもないみたいですね。

 いろいろとありがとうございました。本当に参考になりました。
上総
大ベテラン
会議室デビュー日: 2006/06/22
投稿数: 107
投稿日時: 2007-12-13 21:15
もうすでに解決済みのスレだとは思いますが、Linux上で動作しているPostgreSQLで、
プロセスとアドレスの情報が取得出来る方法がありましたので報告します。

『ps alx』コマンドを叩くと、COMMAND列に『postgres: ユーザー名 データベース名
マシン名(IPアドレス 但しローカル時は[local]) idle』と表示される事が判明
しました。
(Debian上で動作確認済み)

今回のような、テストの間だけと言う区切りであれ実際の運用であれ、Linuxを操作
可能な状態であれば役に立つかと思います。

[ メッセージ編集済み 編集者: 上総 編集日時 2007-12-13 21:21 ]
take11
会議室デビュー日: 2006/02/16
投稿数: 18
投稿日時: 2007-12-13 21:40
いつもいつもありがとうございます。
残念ながら開発端末はWindowsなのでこの方法は今現在は使えないのですが、本番機はLinuxになる予定なので非常に参考になります。
とても勉強になりました。

スキルアップ/キャリアアップ(JOB@IT)