S2Daoで排他制御をする場合のVersionNo推奨について
ひょんなことからS2Daoの排他制御について思うことがあったので書いてみる。
S2Daoの排他制御はTimestampを使用する方法とVersionNoを使用する方法の2通りある。
で、S2Daoを実装しているチームはVersionNoの使用を推奨している。
- http://www.seasar.org/wiki/index.php?FAQ%2FS2DAO#rba69c39
- http://ml.seasar.org/archives/seasar-user/2007-September/010529.html
これは予想だけど、VersionNoを推奨する理由は複数のクライアントやクラスタ構成でも安全に排他制御ができるから。
ソースをみるとS2Daoが更新時に何をするかというとTimestampによる排他制御はアプリケーションサーバの時間を設定して、VersionNoの方は更新対象のBeanのVersionNoをインクリメントするだけ。
問題はTimestampを使用した場合に複数のサーバーがあったりすると、排他制御用のフィールドにたまたま同じ時間が書き込まれる可能性が0ではなく更新を見逃して不正に上書きされることがあり、VersionNoはそういう可能性がないのでVersionNo推薦ということらしい。
で、考えたのが比較的簡単な対応でTimestampの排他制御もVersionNoと同等の安全性が保障できるのではないかということです。
要は排他制御用のフィールドは更新を検出するためのフラグとして機能するので同じ値を書き込まなければ良い。だから更新時にBeanの値と取得したTimestampが同じだったら1nanoずらすとか。ただこれだけだと同じ値が書き込まれる可能性は0にはならないので、Timestampが未来にしか進まないようにすれば安全性はVersionNoと同じになるはず。
厳密にはパフォーマンスが落ちてしまうのとそこまでやる価値があるのか?という判断もあるとは思いますが、排他制御用に専用のフィールドが必要にならなくなるというのは利点としては大きいと思います
まあ、暇なのでそんなことを考えてみましたよということで。