- - PR -
DBへの排他制御の方法について
投稿者 | 投稿内容 | ||||
---|---|---|---|---|---|
|
投稿日時: 2006-05-25 01:32
楽観的ロックの手法についてまとめると、
■ タイムスタンプ方式による行更新の検出 異なるリビジョンを同一視する可能性があるので不完全。 ■ 行バージョン方式による行更新の検出 ロックやUPDATEの方法に問題がなければ確実に検出可能。 ■ UPDATEのWHEREでバージョンを限定する 単独のUPDATEで行えば更新はアトミックに行われるはずなのでOK。 更新結果が1行ならば競合なし、それ以外であれば競合があると見なせる。 ■ SELECT 〜 FOR UPDATE、SELECT 〜 WITH (UPDLOCK) 実際の更新前に行の更新状態を検出する場合は明示的なロックが必要。 ロックをかけない場合は、SELECTとUPDATEの間で処理をアトミックに 実行できる保証がないので不完全。 ■ 更新プロセス(実際はスレッド)を限定する Single Threaded Executionパターンでの実行。 処理の並行性がない。分散環境では破綻する。 といったところになると思います。 | ||||
|
投稿日時: 2006-05-25 01:38
いや、該当部分の担当者が「いくらなんでもあり得ないよなぁ」と勝手に想定したのを テスト段階で暴きだせたわけで、有意義なテストでした。 実例1の方は、人が手でブラウザを操作した場合でも「狙ってやれば」稀に発生しました。 これは、実運用でも(稀であっても)起こり得るということで、修正。 実例2の方は、「性能が一桁上がってもあり得ないから、まあいいんじゃない?」という方に傾きかけたのですが、 「今後の性能向上に期待したい」というPMの決断で、けっきょく修正することに。 (一回のユーザ操作が複数回の更新を引き起こす可能性が「完全には否定できない」ものだったので) | ||||
|
投稿日時: 2006-05-25 06:26
ADO.NETに組み込まれている楽観的ロック(※)はテーブルのすべての列を
チェックする仕掛けになっていますのであまり効率よくないようです。 私はタイムスタンプまたは更新回数列をチェックして楽観的ロックを組み込んでいます。 ※: DataAdapterのUpdateメソッドのこと _________________ ASP.NET+Ajaxサンプル集 | JavaScript+Ajaxサンプル集 | ||||
|
投稿日時: 2006-05-25 09:06
タイムスタンプ列使ってます。
自動生成のSQL文は嫌いなので全部手で書いてます。 >■ タイムスタンプ方式による行更新の検出 >異なるリビジョンを同一視する可能性があるので不完全。 どういう事になるのでしょうか? | ||||
|
投稿日時: 2006-05-25 10:06
coasmさんの例に限って言えば、どちらも想定が間違っていたので十分意味があると思います。実運用で問題がでるのは大抵想定外のところでなので、出来るだけ想定外のテストをするのは大切なことです。 まあ、あまりにも突拍子もないことしすぎても意味ないですが [ メッセージ編集済み 編集者: まいるどきゃっと 編集日時 2006-05-25 10:12 ] | ||||
|
投稿日時: 2006-05-25 10:17
C#でWebアプリケーションを作成してますが
SQLServerのtimestamp列で楽観的ロックを実装しています。 アプリケーションを論理3階層に分けているため(WebUI - BizLogic - DAC) DataAdapterの自動構成ウィザードを使わず、すべてSQL文を手書きしています。
私もこれがどういうことなのか知りたいです。 ちょっと気になりますので。 [ メッセージ編集済み 編集者: takacini 編集日時 2006-05-25 10:20 ] | ||||
|
投稿日時: 2006-05-25 10:28
同一時刻に更新が入った場合は、実際の更新回数(リビジョン)が異なるのに 検出できない可能性がありますよね?それを異なるリビジョンの同一視と 表現しました。 タイムスタンプの実装がミリ秒単位だろうが、マイクロ秒単位だろうが、 精度内での同一時刻に複数回更新が発生しないという保証はありません。 行バージョン方式ではDBMS自体に不具合が無ければ発生しません。 厳密な並行実行制御とはそういったレベルでの話ですから。 CPUをいくつ積んでいようが確実に動くようなものが正しいのです。 他に同じ程度の労力で済むもっと確実な方式があるので、 過去のしがらみがないような場合は選択しない方がいいのでは? #とは言っても現実に問題が出る可能性は極めて低いですけど | ||||
|
投稿日時: 2006-05-25 10:33
>同一時刻に更新が入った場合は、実際の更新回数(リビジョン)が異なるのに
>検出できない可能性がありますよね?それを異なるリビジョンの同一視と >表現しました。 timestamp列といっても中身は時間ではないので 同一時刻に更新が入っても同一にはならないんじゃ? バイナリ値でデータベース内で一意の値が保証されるはず。 |