[pgsql-jp: 31096] Re: 関数によるLOCK の順序
cdb01160
cdb01160 @ hkg.odn.ne.jp
2003年 9月 21日 (日) 10:15:31 JST
佐藤です。
本題からは、外れますが、、、、
誰も書かないようなので、、、、、
試してみました。
1、PostgreSQL 7.3.2 で、testtable を作って、
2、LOCK を発行する関数を作って、
3、insert 文を発行してみました。
動きますね。(vine 旧版ですけど)
で、LOCK の順番、デッドロックになるか? ですけど、
あいにく、このテストは、していません。
試験方法としては、たくさんの人に一生懸命に上のinsert文を発行してもらって、
デッドロックになるかどうか観察する、なんでしょうけど
、、、、、
先ず、テーブルのロックは、トランザクションの初めに行う。
上のような関数がトランザクションの中で使われるとしても、
関数内からロックを発行するのは、好ましくないと思います。
で、
CREATE FUNCTION get_no() RETURNS INTEGER AS '
SELECT MAX(serialno)+1 FROM testtable
'language 'sql';
のような単純な関数を作る。
そして、
begin;
LOCK TABLE testtable IN SHARE ROW EXCLUSIVE MODE;
INSERT INTO testtable VALUES(get_no(),'test2');
commit;
と言うトランザクションを走らせる。
こうすれば、複数の同様のトランザクションが走っても、
一番早く「LOCK」 SQL 文を受け付けられたトランザクションが
テーブルを独占的に占有できるので、デッドロックにはならない。
(理論的にならない。この理論を実装しているデータベースなら
実際に、デッドロックにならない。もし、デッドロックになるようなら、
誰もそのデータベースを使わないでしょう。
)
ロックモードは、ある本から教えてもらった。
(マニュアルの説明は、読み解きにくいです。)
さて、
>今回、serialnoの値が飛び番になってしまうとマズイので、
>sequenceで値を取るのは難しいと考えています。
ですけど、
テーブルの行が削除されると、飛び番になってしまいますよね。
それと、この手の作業は、トリガーにする方が良いと思います。
以上 佐藤賢治
pgsql-jp メーリングリストの案内