dポイントプレゼントキャンペーン実施中!

PostgreSQL8.2とJavaを使ったWebアプリケーションを構築しています。
pgAdminでサーバー状態>ロック で参照してみたところ、AccessShareLockというのが大量に発生していました。
マニュアルを参照してみたところ、

>AccessShareLock を除き,トランザクション内で獲得されたすべての ロックモードは,そのトランザクション実行の間維持されます.

とあり、つまりAccessShareLockはトランザクションの間でも維持されないということだと思うのですが、どうも解放されてはいないようです。

これは通常の(つまり、更新しない)select文を発行したときに発生するロックだと思うのですが、いろいろ調べても、どうもこのAccessShareLockというのをどのくらい気にしたらいいのかがわかりません。
このロックが残っていると、どのようなときに困るでしょうか。
また、解放するためには通常のselectのあとでもcommit(またはrollback)をする必要があるということになるでしょうか。その際にはcommitとrollback、どちらがいいということはあるでしょうか。
ご存じのかたがいらっしゃいましたらご教示いただければと思います。よろしくお願いいたします。

「AccessShareLock はどの程」の質問画像

A 回答 (3件)

回答番号: No.2 に対して訂正があります。



> 手元の psql で確認した限りでは、トランザクション内で SELECT を実
> 行してコミットしていない状態だと、SELECT の対象となっているテーブ
> ルの他にいくつかのシステムカタログに対しても Access Share Lock が
> 取得されたままでした。

と書きましたが、これは psql 内でテーブル名などの補完を行ったためで
した。

いずれにしてもトランザクション内で SELECT を実行してコミットせずに
放置しているのであれば、対象となるテーブルと、そのテーブルに定義さ
れたインデックスにも Access Share Lock が取得されたままとなるので、
トランザクションをコミットするようにしてみてください。

トランザクション内で更新していなければロールバックでも構いません。
    • good
    • 1
この回答へのお礼

ありがとうございました! 締め切らずに待っていたがありました。。(;-;)

なるほどなるほど、やっぱりcommitかrollbackしないといけないのですね。これが残っていると、テストの時などちょっとしたテーブルの修正などができなくてAPサーバーごと停止しないといけないので困っていたのです。
修正箇所が膨大なのでまだ試しておりませんが、きっとこれでうまくいくはずです!
どうもありがとうございました!!

お礼日時:2009/08/19 14:26

添付の画像が小さくて気付かなかったのですが (拡大できるのかな?)、クエリーが「<Idle> in transaction」になっているようです。



「<Idle> in transaction」というのはトランザクションが開始されて次の SQL が実行されるのを待っている状態です。

確か JDBC ではデフォルトで自動的にトランザクションが開始され、また、DBCP などのコネクションプールを使っているとデータベースへの接続が保持されたままとなります。

手元の psql で確認した限りでは、トランザクション内で SELECT を実行してコミットしていない状態だと、SELECT の対象となっているテーブルの他にいくつかのシステムカタログに対しても Access Share Lock が取得されたままでした。

従って、Statement オブジェクトの executeQuery メソッドで SELECT を実行した後に Connection オブジェクトの commit メソッドでトランザクションをコミットしてあげれば、大量に Access Share Lock が取得されている状況は解消されるのではないかと思います。
    • good
    • 0

ご質問にあるように ACCESS SHARE LOCK は通常の SELECT (FOR UPDATE などを指定していない) を実行した場合に暗黙的に取得されるロックのモードです。

従って、ACCESS SHARE LOCK が長時間確保されたままの状態というのは、SELECT の実行に時間がかかっているということです。

ACCESS SHARE LOCK はテーブルロックの中では最も弱いロックなので、残っていたとしてもそれほど問題はありません。問題があるとすれば ACCESS SHARE LOCK と競合する ACCESS EXCLUSIVE を取得する処理、ALTER TABLE、DROP TABLE、TRUNCATE、REINDEX、CLUSTER、VACUUM FULL の実行が待たされることくらいです。

あと、ACCESS SHARE LOCK を開放する方法についてですが、前述のように通常の SELECT を取得されるロックなので、COMMIT や ROLLBACK では対応できません (COMMIT や ROLLBACK が実行されるのは SELECT の実行が完了した後なので)。もし、強制的に ACCESS SHARE LOCK を開放したい場合には SELECT の実行をキャンセルしかありません。

参考URL:http://www.postgresql.jp/document/pg826doc/html/ …
    • good
    • 0
この回答へのお礼

ご回答どうもありがとうございました。
実際に、select文を発行して結果セットを取得し終わってから放置してみたのですが、20分くらいたってもロックは解放されませんでした。
そして、次のselect文を発行すると、前回のロックが全て解放され、新たなロックが生成され、それがずっと解放されない……という繰り返しになっています。

> 従って、ACCESS SHARE LOCK が長時間確保されたままの状態というのは、SELECT の実行に時間がかかっているということです

とのことですが、これはつまり、「selectの終了とはいつのことを指すのか」ということにもつながってくるかと思うのですが、、、
(カテ違いになってしまうかもしれませんが)JDBCで考えると、「selectの終了」とはいつかを考えたとき、思い当たるのは
・executeQuery()メソッドの処理が終わったとき
・結果セットオブジェクト(ResultSet)をクローズしたとき
・ステートメントをクローズしたとき
などなどがあるかと思うのですが、実際にはどういうタイミングかご存じでしょうか?
よろしくお願いいたします。

お礼日時:2009/08/12 22:48

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!

関連するカテゴリからQ&Aを探す