- PR -

ロックの実現方法について

投稿者投稿内容
どせい
大ベテラン
会議室デビュー日: 2006/10/25
投稿数: 145
投稿日時: 2007-01-31 18:06
今更ながら検索結果。
↓だったり、他にも@IT内でも検索して巡ってみるとちょっぴり幸せな気分になれるかも。
http://www.google.co.jp/search?hl=ja&q=%E6%A5%BD%E8%A6%B3%E7%9A%84%E3%83%AD%E3%83%83%E3%82%AF
囚人
ぬし
会議室デビュー日: 2005/08/13
投稿数: 1019
投稿日時: 2007-01-31 20:48
真の仕様がどうなのかわかりませんが、
引用:

このときに、Aさんが編集画面edit.aspxをID=1で開いている場合に
Bさんが同じID=1の編集をクリックし、edit.aspxを開いた場合は
「現在編集中のため編集できません」というメッセージを表示したいのですが
どのように実現すればよいのでしょうか。


という仕様であれば、楽観的ロックではダメじゃないでしょうか?

楽観的ロックは長所ばかりがスポットされがちですが、欠点は「データ編集後に更新できない事がわかる事」です。かなり時間をかけて編集した後、更新できないことが分かって編集結果を破棄しなければならないとしたらどうでしょうか?それでも更新するかどうかをユーザーに選択させるという手もありますが、更に作りこみが必要になります。

悲観的ロックと言うと、DBMS のロック機構を使ってかなりガチガチにロックしてしまうというイメージですが、単に照会時にロックをかける事を悲観的ロックというはずです(たぶん)。

例えば、レコードに「編集中」「編集開始時間」といった列を設け、照会時に「編集中」が有効になっていれば編集できない、しかし、照会時刻が「編集開始時間」から一定時間経っていれば編集権を得る、という実装も考えられます。

このようにすれば、最初に編集権を得たユーザーがブラウザを閉じるなりして放置した場合も対処できます。もちろん、多人数が同時に編集権を得ないように「編集中」等の列を更新する際は排他制御してください。最初に編集権を得た人が単に時間がかかっていただけという事も考慮して、「編集中」ではなく「編集者」という列にしてセッションID等を持たせるのも手でしょう。

このようにすると、DBMS のロック機構を使った場合の「ロック解除」の問題を回避できるのではないでしょうか。
_________________
囚人のジレンマな日々
Jitta
ぬし
会議室デビュー日: 2002/07/05
投稿数: 6267
お住まい・勤務地: 兵庫県・海手
投稿日時: 2007-01-31 22:47
引用:

ぴーたーさんの書き込み(2007-01-31 09:24)より:
>>Jittaさん
この場合はPageの破棄イベントでCommitされていない場合はRollbackとか
コネクションのCloseとかできないもんなんでしょうか。(Disposeとかで)
sessionタイムアウトや、ブラウザの戻るボタンなども、返信頂いたこのケースと
同様な現象が出そうで、どうしようかと思っていました。

Pageロード時にデータをDBからロードし、テーブルをロック。
そのDbTransactionとDbConnectionのインスタンスを一時的にSessionオブジェクトにいれ
そのページが破棄されるときにCommit状態を判定して、必要ならばRollbackを行い、
ロック、DbTransactionとDbConnectionの開放、
Sessionタイムアウトとブラウザの終了(Page破棄イベントにきそうですが)は
Session_OnEndで開放するというのでも問題ありなのでしょうか。


 Page の破棄とは、誰が、どの Page を破棄することを、意味していますか?

 クライアントが、表示しているページを破棄したかどうかは、サーバではわかりません。同じセッションに別のページのリクエストがきたとしても、セッションを引き継ぐようにして新しいブラウザを起動して、新しいブラウザから要求を出したかもしれません。
 サーバの Page オブジェクトの破棄であれば、クライアントが表示した時点(正確には、サーバがページデータを送り出した後、不確定なタイミング)で、Page オブジェクトは破棄されます。Unload は、メモリから下ろされるときに発生するので、この時点で発生します。このタイミングで Rollback すると、ユーザ B も編集可能になります。

 HTTP 通信がどの様に行われるかは、おおよそでも把握されているでしょうか。Web アプリケーションは、1リクエストを処理する間を越えて、データベース接続などのオブジェクトを保持することはしません。このため、「悲観的ロック」は用いません。


引用:

Session_Endで・・と書きましたが、InProcモードは使わないほうがいいみたいですね。
Session_Endに依存した処理もだめのようで。


 Session の End イベントが発生するのは、InProc の時だけですよ?
 Web アプリでは、Win アプリと考え方を大幅に変えなければなりません。悲観的ロックはあきらめる方がよいしょう。
 囚人さんの案も一理ありますが、いつまでロックしておくか、というところがはっきりしていませんので、「あきらめろ」としておきます。
_________________
ぴーたー
会議室デビュー日: 2007/01/30
投稿数: 9
投稿日時: 2007-02-01 09:27
>>Jittaさん
Pageの破棄とは、System.Web.UI.Pageオブジェクトのことを指しています。

>>サーバの Page オブジェクトの破棄であれば、クライアントが表示した時点
なぜ、Pageが描画前に破棄されるのだろうと思っていたのですが、上記のことを
考えると当然な気がします。
頭をWEBサーバのメモリとクライアントのメモリを分けて考えられていませんでした。
こう考えるとUnloadのタイミングも納得行きました、ありがとうございます。

>>Web アプリケーションは、1リクエストを処理する間を越えて、
>>データベース接続などのオブジェクトを保持することはしません
通信方法はおおまか把握しているつもりでしたが、なんとか1リクエストを処理する間を
越えてロックを保持できるのかと考えておりました。
ですが、みなさんの意見を聞いている間に通信方法からすると悲観的ロックは
できないのではないかという結論に自分ながら解釈しておりました。

>>Session の End イベントが発生するのは、InProc の時だけ
これは把握していたのですが、
http://blogs.wankuma.com/naka/archive/2006/03/16/21958.aspx
この当たりの記事を読み違えていたようです、すみません。


>>囚人さん
時間的な自前でのロックも調べている間にどこかで見つけていました。
現在の業務調査で楽観的でいけそうという判断がありましたので
今回はそちらを採用しようと思います。
時間的ロックについて詳細を記載いただき、ありがとうございます。
また参考にさせていただきます。


>>どせいさん
何度も返信ありがとうございます。
記載頂いた先も参照させていただきます。
Jitta
ぬし
会議室デビュー日: 2002/07/05
投稿数: 6267
お住まい・勤務地: 兵庫県・海手
投稿日時: 2007-02-05 22:46
思いつき
http://blogs.wankuma.com/jitta/archive/2007/02/05/61043.aspx
_________________

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