- - PR -
DBへの排他制御の方法について
投稿者 | 投稿内容 | ||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
投稿日時: 2006-05-24 18:59
囚人さんへ
確かに完動する形でソースとか出したいのですが。。 もう4ヶ月あまりの時が経っているので それがどこだったか。。って覚えて無いです。。 や、でもintとstringとかは比較てないことは確実です^^;
えーと一応確認の意味で たとえば、int と longの1を比較した場合 (==)ではTrue (equals)ではFalse ですので、囚人さんの仰ってるように String限定ってことですよね。 (==)は暗黙的に変換できるものは暗黙変換のもので比較 (equals)はオブジェクト自身を比較
そういう違いがあったんですね。。。 そのあたりも知りませんでしたね。。 #知らないことが多いなぁ(つд`) #勉強になります('▽')ゝ | ||||||||||||
|
投稿日時: 2006-05-24 19:07
かいといてくれんと、そこまでよみとれへんよー。 釣られちゃったがなーww | ||||||||||||
|
投稿日時: 2006-05-24 19:27
だいぶ脱線気味ですが、本題に戻りつつ・・・
排他と言うとちょっと違うかもしれませんが、楽観的ロック、悲観的ロックの以外の方法として・・・。 ・データベース(テーブル)の更新を一つのプロセスに委託する。一つのプロセスからしか更新を行わないので、当然排他処理も不要になる。データベースの更新を行うプロセスへの要求は、各クライアントから何らかの方法(ケースバイケース)で送る。 ・トライ&エラー。テーブルへの制約条件やトリガーによって、不当な更新や追加がエラーとなる様にする。 と言う方法もあるかと。 | ||||||||||||
|
投稿日時: 2006-05-24 20:48
> [思い切り取得(SELECT)して、
select 〜 for update no waitなどでロックして、 >コード(C#等の)上で比較(IF 〜)して、 >更新(UPDATE) すれば如何でしょ。 | ||||||||||||
|
投稿日時: 2006-05-24 22:47
更新日付の更新は、トリガでやらせています。コーディングする人に「こうやって更新してね」といって、その通りにしてくれるかわからないから。 って、更新日付のチェックを必ずしてくれるとも限らないのですけどね。 | ||||||||||||
|
投稿日時: 2006-05-24 23:15
脱線したままで申し訳ないですが、確認への回答を。。。
同じですよ、値型もStringも (==)は同値比較、 (Equals)は同型の同値比較、 です。 ただ、Stringには値型の様な異型の同値が存在しないだけです。 [ メッセージ編集済み 編集者: うにくま 編集日時 2006-05-24 23:17 ] | ||||||||||||
|
投稿日時: 2006-05-25 00:14
本題の方の話題ですが、楽観的ロックのキーとして最終更新日時を使うのは避けた方が良いです。
(0) 直前の更新 (1) セッションAがレコードを読み出し。 (2) セッションBがレコードを読み出し。 (3) セッションAが(1)のデータに基づいてレコードを更新。 (4) セッションBが(2)のデータ(1と同一)に基づいてレコードを更新。 という流れで、(0)〜(3)が同一時刻値に起こると、本来なら拒否すべき(4)の更新を受け入れてしまいます。 実例1 更新時刻の単位は秒。 webシステムだったので、秒単位で同一レコードが繰り返し更新されることはないと予測。 負荷テストのための自動ツールを複数動かしたら、見事に破綻(笑)。 実例2 更新時刻の単位はミリ秒。 同一レコードが1ミリ秒以内に繰り返し更新されることは性能上あり得ないと予測。 データベース代わりのスタブモジュールを使ったユニットテストで、排他制御関係が全滅(笑) 「上手くいかない可能性があるものは、結局上手くいかないのだ」という見本ですな。 以来、更新毎にインクリメントしていくカラムを持たせるようにしています。 | ||||||||||||
|
投稿日時: 2006-05-25 00:19
安易に更新時刻を使うのがいいとは言いませんが、そもそもテストが間違ってるでしょう。 システムの想定(それも暗黙ではなく明確に想定したもの)を大幅に覆すテストに意味があるとは思えません。 ※こういうテストの仕方もするので最初から避けておくという判断はまああるかもしれませんが。 |