オプティミスティックロック


Kuznetsovのドキュメントはおもろいかも。

http://www7b.software.ibm.com/dmdd/library/techarticle/0209kuznetsov/0209kuznetsov.html


何か画面を表示して、内容を修正して修正ボタンを押すまでに
他の誰かが同じレコードを修正していた場合「更新の消失」が発生する。
他の誰かの更新が上書きされるからである。


分散キャッシュの参照と更新時も同じ。
キャッシュはデータベースの内容と同期していないので
キャッシュの内容を見て更新するまでに
他の誰かが同じレコードを修正していた場合「更新の消失」が発生する。


要するに「更新の消失」はよくある話なのだ。



表にバージョンを表現する列を追加して

更新するたびに値を増やしていく。
更新はselect for updateでアトミックにおこなう。

誰かがすでに更新していたらバージョンがあがっているので
「更新の消失」を防ぐことができる。

2つの更新が競合したことがわかったあとの処理は
アプリケーションによっていろいろ。

画面に既に更新されたエラーメッセージを表示したり。








SEQUECEオブジェクト

SEQUECEオブジェクトを普通に使うと
新しい値を取得するのにDBサーバに一回アクセスしなければならず、
ネットワークトラフィックを1往復分増加してしまう。

Kuznetsovの例ではクラスタのJavaVM単位にあらかじめ
UNIQナンバーをまとめて送っておく仕掛けがのっている。










AD

バージョンの値の更新がアトミックにできないような
ロック制御を持たないLDAPがある。

MicrosoftのActive Directoryのレプリケーション時の
更新の競合の解決方法はかなり強引にやってる。

http://msdn.microsoft.com/library/en-us/dnactdir/html/avrepad.asp


競合の解決

When a DC receives an update request from two replicas for the same object, 
it first compares the version numbers of the replicas. 

The DC accepts the update request with the highest version number as the new value for the object. 
If both update requests have the same version number, this will constitute a collision and will be logged as such. 

To resolve the collision, the DC accepts the update request with the latest timestamp. 

If both requests have the same timestamp, the DC accepts the request that was received first. 

The version number takes precedence over the timestamp when reconciling updates of the same object from multiple DCs. 
This avoids the possibility that a DC with an incorrectly lagging time inadvertently causes the rejection of some of its updates by a receiving DC.


DC(ドメインコントローラ)が同じオブジェクトの更新を2つの複製から受信したとき
まずレプリカのバージョンナンバーを比べる。

DCはバージョンナンバーのもっとも高いリクエストの更新を受け付けて値を更新する。
もし、バージョンナンバーが同じだったら競合が起こったことをログする。

この競合を解決するためにDC更新日付の一番新しい更新を受け付ける。

両方の更新日付が同じだった場合、DCは最初に到着した更新を受け付ける。

複数のDCからの同じオブジェクトのの更新を調整するときはバージョンナンバーが更新時刻より優先される。

この方式で、受信DCが更新を拒否した場合に発生する
意図していない遅延時間が原因でDCが不正な状態になる可能性を防ぐ。









時価

そういえば、株価は時価なので数秒おきにQuote会社から受信される。

Quote会社が複数あって、同じ銘柄の値段をどうやってデータベースに取り込むか
処理と同じだな。

アプリケーションのロジックで十分解決できる問題なのだと思う。








キャッシュの同期

トリガーはそれを起動したとトランザクションとして実行される。
更新トランザクションと分散キャッシュの更新は完全に同期を取れる。

キャッシュの更新に失敗したらトランザクションをロールバックさせるだけである。

重要なオブジェクトのキャッシュは、表と同期が取れてなければならないので
各クラスタのキャッシュの更新まで行う。

キャッシュの更新ポリシーをいろいろ用意しておく。

End of FILE.




2003/08/22 ugya@lycos.com