- PR -

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

投稿者投稿内容
take11
会議室デビュー日: 2006/02/16
投稿数: 18
投稿日時: 2007-10-24 16:10
現在PostgreSQL8.0を使用したWebアプリを開発しています。
で、テストの時などにselect 〜 for updateなどのSQLを
発行して、commitする前にエラーが発生してアプリケーションが
終了してしまった場合などに、このトランザクションを手動で
ロールバックしてやらないといけないと思っていますが、
どうしたらできるのかわかりません。
pgAdminIIIでツール>サーバー状態などでロックの一覧などは
見られると思うのですが、どれが自分のものなのか……

ごくごく基本的な質問で恐縮ですが、教えていただければ幸いです。
よろしくお願いいたします。
もしもし
ぬし
会議室デビュー日: 2004/10/15
投稿数: 280
投稿日時: 2007-10-24 16:52
以下のような記載を見つけました。

http://www.sraoss.co.jp/technology/postgresql/faq.php
10. リカバリ機能は?

もっと詳しい内容であれば PostgreSQL のマニュアルとかに記載はあるかと。

# 想定しているエラーの内容が不明ですが、
# 普通は勝手にロールバックしてくれるだろうと
# 思われ...
_________________
もしもし@RMAN 友の会

[ メッセージ編集済み 編集者: もしもし 編集日時 2007-10-24 16:54 ]
take11
会議室デビュー日: 2006/02/16
投稿数: 18
投稿日時: 2007-10-24 17:24
ありがとうございました。

> トランザクション中にユーザの SQL 文に間違いがあった場合
> トランザクション中にフロントエンドプロセスが異常終了した場合
> トランザクション中に PostgreSQL サーバマシンが停電などで停止した場合
> PostgreSQL の処理としては正常だが、業務的には誤ってデータを更新してしまった場合

というのがありますが、
私の場合は、自分が作成したWebアプリケーションは終わっていますが、DBに
接続にいっているTomcatは生きているので、トランザクションは
生きたままになって、レコードもロックされたままでいるのではないかと
思っています。
今まではTomcatを再起動したりPostgreを再起動したりしていたのですが、
これから結合テストに入ると勝手にサーバを落としたりできなくなるので
どうしようかと思っています。

[ メッセージ編集済み 編集者: take11 編集日時 2007-10-24 17:40 ]
かつのり
ぬし
会議室デビュー日: 2004/03/18
投稿数: 2015
お住まい・勤務地: 札幌
投稿日時: 2007-10-24 18:29
1.例外が発生するのはバグである
2.例外が発生しないようにテストをしている
3.だから例外対策はしなくてもよい
4.でも人間にはミスがあるので例外が発生したら戻せるようにしたい

という感じでアプリを作られているのかなと思いました。
そもそも論を言ってしまうと、アプリの作りが完全に間違っています。

成功しても失敗してもトランザクションが完了するように作らなければなりません。
そのためには、try-catch-finallyを的確に使用する必要があります。

以下はほんの一例です。
コード:
try{
    ...業務ロジック
}catch(XXXException e){
    ...例外処理
}finally{
    ...トランザクションの完了
}


take11
会議室デビュー日: 2006/02/16
投稿数: 18
投稿日時: 2007-10-24 18:55
かつのりさん

ありがとうございます。
例外については例外を処理する専用のモジュールがあるので、
個々のモジュールで勝手にcatchすることを禁止されています。
ただ、それとつなげるのは結構先なので、それまではどうしようかと
思っています。
かつのり
ぬし
会議室デビュー日: 2004/03/18
投稿数: 2015
お住まい・勤務地: 札幌
投稿日時: 2007-10-24 20:32
キャッチしないなら、
コード:
try{
    ...業務ロジック
}finally{
    ...トランザクションの完了
}


という書き方もありますよ。

上位クラスでトランザクションまで責任を持たないのであれば、
必ずfinally節を使いましょう。
take11
会議室デビュー日: 2006/02/16
投稿数: 18
投稿日時: 2007-10-24 22:46
かつのりさん

どうもありがとうございます。
で、せっかくアドバイスをいただいているのに非常に申し訳ないのですが、
実は最終的には個々のモジュールからSQL文を発行することも禁止されていて、
許されているのはSQL文を作成するところまでです。
それをコネクションやらを一括管理しているDB管理モジュールに渡す、というのが
最終形態なのですが、そのモジュールができるのを待っていたら単体テストもSQLの
チューニングもできないので、最終結合テスト前の段階までは、作成したSQL文を
個々のモジュールから直接発行して開発を進める、という体制で動いています。

#けっこう一般的な方法だと思っていたのですが、そうでもないのでしょうか。。

で、そのような開発方法の是非や、プログラムロジックの是非はとりあえず
おいておいて、Postgreで手動でロックを解除する方法があるのなら知りたいと
思っている次第です。
私はあまり詳しくないのですが、Oracleなら簡単にできるそうなのですが、今回は
Postgreなので方法があるなら知りたいと思っています。

ただそれとは別に、tryでcatchせずにfinallyを使用するという方法は初めて
知りました。とても勉強になりました。ありがとうございます。
かつのり
ぬし
会議室デビュー日: 2004/03/18
投稿数: 2015
お住まい・勤務地: 札幌
投稿日時: 2007-10-24 23:54
なるほど。質問の意図は分かりました。

方法としてはpg_lcoksを見て、
該当するpidに対してkillするしか思いつかないですね。

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