- PR -

DBへの排他制御の方法について

投稿者投稿内容
あしゅ
ぬし
会議室デビュー日: 2005/08/05
投稿数: 613
投稿日時: 2006-05-25 01:32
楽観的ロックの手法についてまとめると、

■ タイムスタンプ方式による行更新の検出

異なるリビジョンを同一視する可能性があるので不完全。

■ 行バージョン方式による行更新の検出

ロックやUPDATEの方法に問題がなければ確実に検出可能。

■ UPDATEのWHEREでバージョンを限定する

単独のUPDATEで行えば更新はアトミックに行われるはずなのでOK。
更新結果が1行ならば競合なし、それ以外であれば競合があると見なせる。

■ SELECT 〜 FOR UPDATE、SELECT 〜 WITH (UPDLOCK)

実際の更新前に行の更新状態を検出する場合は明示的なロックが必要。
ロックをかけない場合は、SELECTとUPDATEの間で処理をアトミックに
実行できる保証がないので不完全。

■ 更新プロセス(実際はスレッド)を限定する

Single Threaded Executionパターンでの実行。
処理の並行性がない。分散環境では破綻する。

といったところになると思います。
coasm
大ベテラン
会議室デビュー日: 2001/11/26
投稿数: 237
投稿日時: 2006-05-25 01:38
引用:

システムの想定(それも暗黙ではなく明確に想定したもの)を大幅に覆すテストに意味があるとは思えません。



いや、該当部分の担当者が「いくらなんでもあり得ないよなぁ」と勝手に想定したのを
テスト段階で暴きだせたわけで、有意義なテストでした。

実例1の方は、人が手でブラウザを操作した場合でも「狙ってやれば」稀に発生しました。
これは、実運用でも(稀であっても)起こり得るということで、修正。

実例2の方は、「性能が一桁上がってもあり得ないから、まあいいんじゃない?」という方に傾きかけたのですが、
「今後の性能向上に期待したい」というPMの決断で、けっきょく修正することに。
(一回のユーザ操作が複数回の更新を引き起こす可能性が「完全には否定できない」ものだったので)
Access
ぬし
会議室デビュー日: 2002/04/08
投稿数: 829
投稿日時: 2006-05-25 06:26
ADO.NETに組み込まれている楽観的ロック(※)はテーブルのすべての列を
チェックする仕掛けになっていますのであまり効率よくないようです。

私はタイムスタンプまたは更新回数列をチェックして楽観的ロックを組み込んでいます。

※: DataAdapterのUpdateメソッドのこと
_________________
ASP.NET+Ajaxサンプル集 | JavaScript+Ajaxサンプル集
めだか
大ベテラン
会議室デビュー日: 2004/11/11
投稿数: 109
投稿日時: 2006-05-25 09:06
タイムスタンプ列使ってます。
自動生成のSQL文は嫌いなので全部手で書いてます。


>■ タイムスタンプ方式による行更新の検出
>異なるリビジョンを同一視する可能性があるので不完全。

どういう事になるのでしょうか?
まいるどきゃっと
大ベテラン
会議室デビュー日: 2004/08/12
投稿数: 135
お住まい・勤務地: 群馬
投稿日時: 2006-05-25 10:06
引用:

なちゃさんの書き込み (2006-05-25 00:19) より:

安易に更新時刻を使うのがいいとは言いませんが、そもそもテストが間違ってるでしょう。
システムの想定(それも暗黙ではなく明確に想定したもの)を大幅に覆すテストに意味があるとは思えません。

※こういうテストの仕方もするので最初から避けておくという判断はまああるかもしれませんが。



coasmさんの例に限って言えば、どちらも想定が間違っていたので十分意味があると思います。実運用で問題がでるのは大抵想定外のところでなので、出来るだけ想定外のテストをするのは大切なことです。

まあ、あまりにも突拍子もないことしすぎても意味ないですが

[ メッセージ編集済み 編集者: まいるどきゃっと 編集日時 2006-05-25 10:12 ]
takacini
常連さん
会議室デビュー日: 2005/12/27
投稿数: 24
お住まい・勤務地: 東京都
投稿日時: 2006-05-25 10:17
C#でWebアプリケーションを作成してますが
SQLServerのtimestamp列で楽観的ロックを実装しています。

アプリケーションを論理3階層に分けているため(WebUI - BizLogic - DAC)
DataAdapterの自動構成ウィザードを使わず、すべてSQL文を手書きしています。

引用:

■ タイムスタンプ方式による行更新の検出
異なるリビジョンを同一視する可能性があるので不完全。


私もこれがどういうことなのか知りたいです。
ちょっと気になりますので。


[ メッセージ編集済み 編集者: takacini 編集日時 2006-05-25 10:20 ]
あしゅ
ぬし
会議室デビュー日: 2005/08/05
投稿数: 613
投稿日時: 2006-05-25 10:28
引用:

めだかさんの書き込み (2006-05-25 09:06) より:
>■ タイムスタンプ方式による行更新の検出
>異なるリビジョンを同一視する可能性があるので不完全。

どういう事になるのでしょうか?


同一時刻に更新が入った場合は、実際の更新回数(リビジョン)が異なるのに
検出できない可能性がありますよね?それを異なるリビジョンの同一視と
表現しました。

タイムスタンプの実装がミリ秒単位だろうが、マイクロ秒単位だろうが、
精度内での同一時刻に複数回更新が発生しないという保証はありません。
行バージョン方式ではDBMS自体に不具合が無ければ発生しません。

厳密な並行実行制御とはそういったレベルでの話ですから。
CPUをいくつ積んでいようが確実に動くようなものが正しいのです。

他に同じ程度の労力で済むもっと確実な方式があるので、
過去のしがらみがないような場合は選択しない方がいいのでは?

#とは言っても現実に問題が出る可能性は極めて低いですけど
めだか
大ベテラン
会議室デビュー日: 2004/11/11
投稿数: 109
投稿日時: 2006-05-25 10:33
>同一時刻に更新が入った場合は、実際の更新回数(リビジョン)が異なるのに
>検出できない可能性がありますよね?それを異なるリビジョンの同一視と
>表現しました。

timestamp列といっても中身は時間ではないので
同一時刻に更新が入っても同一にはならないんじゃ?
バイナリ値でデータベース内で一意の値が保証されるはず。

スキルアップ/キャリアアップ(JOB@IT)