3

asp.net ページのロックに関する問題に直面しています。最初に開いたユーザーのためにそのページをロックする必要があるユーザー プロファイル ページがあります。詳細は次のとおりです。データベースには多くのユーザー プロファイル レコードがあり、レコード番号をクエリ文字列に渡して特定のページを開きます。ユーザーがグリッドのリンクボタンをクリックし、レコードを読み取り専用モードで開きます。すべてのコントロールを有効にし、クリックするとユーザーが使用できるようにする編集ボタンがあります。タスクは、最初に編集ボタンをクリックしたユーザーにレコードをロックすることです。

これとは別に、ユーザーがページから移動したり、途中でページを閉じたりするなど、多くのシナリオがあります。このような場合、レコードは他のユーザーが利用できる必要があります。シナリオを解決する方法のいくつかの可能なアプローチまたは例を教えてください。

前もって感謝します

4

7 に答える 7

2

あなたが言及したすべての理由から、これは本当に悪い考えだと思いますが、私がこれをしなければならなかった場合、私することはASP.NETキャッシュを使用することです。

だから、このようなもの:

    Cache.Add(someUniqueKeyForAUserProfile, theUserThatLockedTheRecord, null, 
    DateTime.Now.AddSeconds(120), Cache.NoSlidingExpiration, CacheItemPriority.Normal, 
    UnlockRecord)

    private static void UnlockRecord(string key, object value, CacheItemRemovedReason reason) {
       //This particular record went longer than 2 minutes without 
       //the user doing anything, do any additional cleanup here you like
    }

次に、ページで次のようなことを行うことができます。

if (Cache[someUniqueKeyForAUserProfile] != theUserThatLockedTheRecord){
  //Tell the user they can't access the page
}

ここでの良い点は、組み込みのASP.NETキャッシュを使用して、2分後にレコードを自動的に「ロック解除」することです。だからあなたはそれらすべてを無料で手に入れます。

于 2011-08-29T01:19:30.673 に答える
2

レコードをロックしようとすると、100% 古いロックが取得されます。つまり、これらの古いロックを削除するプロセスが必要になります。

同時変更を防止するだけの場合は、タイムスタンプまたはバージョン フィールドを使用してこれを行うことができます。レコードを編集するときは、バージョン/タイムスタンプを隠しフィールドに入れます。次に、更新を適用しようとすると、最初に ID に対応するデータを再読み込みし、データベースから返されたバージョンを非表示フィールドのバージョンと照合します。それらが一致する場合は、先に進んで変更を適用しても安全です。そうでない場合は、続行する方法を決定するためのロジックを適用できます。

于 2011-08-29T01:24:19.627 に答える
2

ユーザーエクスペリエンスを向上させるために、ユーザーがJavaScriptを使用して「編集」をクリックした後、ページにハートビートを設定します。5 秒ごと、またはより適切な間隔でサーバーに ping を送信します。したがって、ユーザーが何らかの理由で切断した場合、ユーザーが最後にページに ping を実行した時間を確認するスレッドをスピンオフすることで、ロックをすばやく解放できます。サーバーキャッシュやおそらくセッションなど、どこかにping時間を保存する必要がありますが、負荷分散のためにmemcacheのような分散キャッシュをお勧めします(ただし、環境では重要ではないかもしれません)。

ロック自体はかなり簡単に実装できるはずですが、memcache のような分散キャッシュ ソリューションか、データベースのタイムスタンプ列のいずれかを使用することをお勧めします。ハートビートで期限切れにならない場合に備えて、フェイルセーフの有効期限も含めます。

于 2011-08-31T01:33:45.027 に答える
1

私は同様のシステムで作業しましたが、この場合、データベースのレコードにビットを設定して、編集中であることを示しています。ただし、あなたの場合とは異なり、システムのエンドユーザーには、[保存]または[キャンセル]をクリックしてビットを裏返し、他のユーザーがレコードを編集できるようにする必要があるという期待を設定することができました。正直なところ、ユーザーがページを放棄した場合の対処方法は完全にはわかりませんが、特定の期間ロックされた場合にレコードを解放するsprocを実行するスケジュールされたタスクがあることが頭に浮かびます。時間(これは、レコードがいつロックされたかを示すために日時フィールドも必要になることを意味します)。

于 2011-08-29T01:17:24.870 に答える
1

ユーザーのブラウザが閉じているかどうかを判断できないため、これは不可能です。ブラウザが毎分Webサイトをポーリングする(pingなど)などの操作を行うことで、ブラウザが閉じたと推測するなどのばかげたことを行うことができますが、私はそのルートには行きません。セッションでslideExpirationを使用することもできますが、私にとっては、セッションは「ロック」ページではなく、セッションに使用する必要があります。

たぶん、ページ名のキャッシュされた値をキャッシュに保持します。これは、たとえば10分の有効期限でファイルをロックしたユーザーの記録を保持します。別のユーザーがファイルを要求した場合、コードは最初にページ名がキャッシュにあるかどうかを確認します。同じユーザーが同じファイルを要求した場合(つまり、ポストバックまたは更新を実行した場合)、キャッシュを更新(つまり、タイマーをリセット)すると、さらに10分かかります。ユーザーが長文の手紙を書いていて、ページを投稿または更新しておらず、10分が経過している場合、9分後にトリガーされ、ユーザーに「あなたの時間ページは1分で終了します。[OK]をクリックして、さらに10分間時間を延長してください。」

これが素晴らしい解決策だと言っているわけではありませんが、それはアイデアです。私が知っていることは、ブラウザが閉じているかどうかわからないので、箱の外で考える必要があるということです。

于 2011-08-31T01:09:22.193 に答える
1

@Brian Driscoll は、データベース レコードにビットを設定したと言います。次に、[保存] または [キャンセル] をクリックする必要があることをユーザーに伝えます。本当に?これには非常に多くの問題があります。

インタラクション デザインのルール 1「ユーザー」は、期待どおりのことをしません。

ロックのルール 1 - ロックの解放を担当するアクターが失敗する可能性がある場合、それは失敗します。ショック療法によってユーザーベースをトレーニングできたとしても、コンピューターが故障したり、データベースが故障したり、接続が失敗したり、ネットワークが故障したり、編集の途中でユーザーが死亡したりする可能性があります。

もののロックのルール 2 - もののロックのルール 1 が有効な場合、アウトが必要です。具体的には、タイムアウトまたは孤立したロックを解放する他の方法です。

WikiPedia には、読む価値のあるロックについて書かれたものがたくさんあります。ファイルのロックとスレッド関連のロック (ミューテックス、セマフォなど) は、この問題によく似ており、それらがどのように機能するかを理解することが出発点として適しています。ユーザーは、実際には別の外部並列処理ユニットですよね?

私の意見では、@Michael Yoonは非常に興味深い答えを出しています。まさにこのタイプのページベースのロックを実装する過程にあり、これが現在システムで行っていることですが、ロックを拡張するためにサーバーに常にpingを実行するというYoonのアイデアに似たものに変更します.

  1. ユーザーが編集をクリック
  2. 編集対象のアイテムのロックを要求 (持続時間 5 分?) を取得
    • 成功時 GOTO 3
    • 失敗時にユーザーロックが取得されていないことを通知
  3. ロック トークンによって返されたアイテムのバージョンを確認する
    • バージョンが同じ場合 (古いことはありませんよね?) GOTO 5
    • バージョンの方が新しい場合 GOTO 4
  4. サーバーからアイテムの最新バージョンを取得する
  5. 編集モードに入る
  6. ロックの経過時間を定期的にテストし、ロックの有効期限が近づいたときにユーザーに通知します

具体的には、アイテム 6 を Yoon のアイデアに置き換えて、ユーザーを通知で煩わすのではなく、おそらく 30 秒の「マイクロロック期間」を使用し、クライアントからのロック期間を 30 秒以上延長してロックをアクティブに保つようにします。

于 2011-12-22T18:16:02.217 に答える
0

それはウェブ上で行うのは難しいことです。User1がデータにアクセスするときは、データベースでTimeStampを使用することをお勧めします。次に、User1に手動でページのロックを解除する方法を提供し、TimeStampを利用してタイムアウト値を使用して、User1がページを放棄した場合(ナビゲート、ブラウザを閉じる、インターネット接続を失うなど)、User2のレコードのロックを自動的に解除します。 。

于 2011-08-29T01:18:18.000 に答える