[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 メーリングリストの案内