[PGメモ]Select~for updateによるID生成 | Late Riser

Late Riser

ダメ主婦ミルミルのプログラムと道の駅ドライブとリラックマの日々。
プログラム系は情報提供ではなく個人的メモなので、信憑性薄め。

●Select~for updateによるID生成

あまり使ったことはないが、これによるAUTO_INCREMENT的ID割付というのも手法としてはあるようだ。

◆7.5.9.3. ロックを取得する読み取り SELECT ... FOR UPDATE および SELECT ... LOCK IN SHARE MODE
http://dev.mysql.com/doc/refman/4.1/ja/innodb-locking-reads.html


使い方はこちら

1.トランザクション開始
2.SELECT FOR UPDATE
3.UPDATE
4.トランザクション終了(commit)

要はトランザクションかけて、SELECT FOR UPDATEでUPDATE対象範囲に排他ロックをかけて
その時の値を参照にUPDATEするというもの

ロックの期間はFOR UPDATE指定でSELECT実行~トランザクション終了まで。


[[sample]]
SELECT max(id) max_id FROM stack_table FOR UPDATE;
insert into stack_table (id,name) values ((max_id + 1),'えがちゃん');

ただし、これだと複数セッションが頻繁にInsertをしにアクセスするような場合、
排他ロックにひっかかりまともに動かなくなってしまう事になります。
4スレッドでガシガシアクセスしてみたらもうエライ事に・・・(--;


ぶっちゃけ「マルチタスクのAUTO_INCREMENT代用には向かない」。


ロックした上でのカウンター集計なんか場合には良いのかもしれん。
もしくは、ロック対象が限定的で他セッションと競合しない場合なら。

[[sample]]
SELECT COUNTER_FIELD FROM CHILD_CODES FOR UPDATE;
UPDATE CHILD_CODES SET COUNTER_FIELD = COUNTER_FIELD + 1;




ちなみに
5.1になるとAUTO_INCREMENTのID取得に利用されているようです

13.5.6.3. AUTO_INCREMENT カラムが InnoDB 内でどのように機能するか
http://dev.mysql.com/doc/refman/5.1/ja/innodb-auto-increment-column.html

でもまぁ、・・・5.0だからな。今。あぁ不便。