wikiスタイルのWebサイトで書き込みと書き込みの競合を防ぐにはどうすればよいですか?
質問
WikiスタイルのWebサイトで、書き込み-書き込みの競合を防止または軽減するためにできることサイトの迅速な実行を許可し、サイトを使いやすく保ちますか
私が予見する問題はこれです:
- ユーザーAはファイルの編集を開始します
- ユーザーBはファイルの編集を開始します
- ユーザーAはファイルの編集を終了します
- ユーザーBがファイルの編集を終了し、誤ってユーザーAのすべての編集を上書きする
ここで私が思いついたいくつかのアプローチがありました:
- ある種のチェックアウト/チェックイン/ロックシステムを持っています(ただし、ユーザーがファイルをチェックアウトし続けるのを防ぐ方法がわからないが、「長すぎる」ので、ユーザーをイライラさせたくない編集を許可されていないことにより)
- ユーザーが変更をコミットしたときに行われた他の変更を表示する diff システムを用意してください。ある種のマージを許可します(ただし、これを作成するのは難しく、サイトを「使いづらくなりすぎます」
- 同時編集のユーザーに変更を行っている間 通知します(ある種のAJAX?)
これに行く他の方法はありますか?これをうまく実装しているサイトの例はありますか?
他のヒント
3者間マージ:最初に指摘することは、ほとんどの同時編集、特に長いドキュメントでは、テキストの異なるセクションに対する編集であることです。その結果、ユーザーAとBがどのリビジョンを取得したかに注目することで、 Guiffy Softwareのビルリッチャー。 3者間マージでは、元の箇所から編集が行われた場所を識別でき、衝突しない限り、両方の編集を静かに新しい記事にマージできます。理想的には、この時点でマージを実行し、ユーザーBに新しいドキュメントを表示して、さらに修正することを選択できるようにします。
衝突の解決: これにより、両方のエディターが同じセクションを編集した場合のシナリオが残ります。この場合、他のすべてをマージし、3つのバージョンのテキストをユーザーBに提供します(つまり、オリジナルを含めます)-テキストボックス内のユーザーAのバージョンまたはユーザーBのいずれかを使用します。その選択は、デフォルトで最新のものを受け入れるか(ユーザーが[保存]をクリックしてバージョンを保持するか)、エディターに2回編集を強制して変更を反映するか(エディターAに変更を再適用する必要があるか)に依存しますセクションのバージョン)。
このように3者間マージを使用すると、ロックアウトを回避できます。ロックアウトは、Web上でうまく処理するのが非常に困難です(どのくらいの期間ロックを保持しますか?)。 、これはフォーラムスタイルの応答に対してのみ有効です。また、Webの応答後スタイルも保持されます。
少しAjaxを行いたい場合は、ユーザーAのバージョンをユーザーBのバージョンに編集中に動的に3方向にマージし、 、通知します。今では印象的です。
Mediawikiでは、サーバーは最初の変更を受け入れ、2番目の編集が保存されると競合ページが表示され、2番目の人が2つの変更をマージします。 Wikipedia:Help:Edit Conflicts
をご覧ください。ロック機構を使用するのがおそらく実装が最も簡単でしょう。各記事には、それに関連付けられたロックフィールドとロック時間を設定できます。ロック時間が設定値を超えた場合は、ロックが無効であると見なし、編集のために記事をチェックアウトするときにロックを削除します。また、開いているロックを追跡し、セッションを閉じるときにそれらを削除することもできます。また、2人が編集できるように、チェックアウトしたバージョンの更新をチェックインできるように、データベースに同時実行制御(自動生成されたタイムスタンプなど)を実装する必要もあります。同時に記事。正しいバージョンを持つもののみが編集を正常にチェックインできます。
差分を作成するために使用できる差分エンジンを見つけることもできますが、Wikiエディターで表示するのは問題がある場合があります。実際に差分を表示することは、差分を作成するよりも難しいでしょう。編集を拒否してdiffを実行する必要があるタイミングを検出するには、バージョン管理システムに依存します。
Gmailで、メールへの返信を作成していて、入力中に他の人が返信を送信すると、新しい更新があることを示すポップアップが表示され、更新自体はページのリロードなしの別の投稿として表示されます。このアプローチはあなたのニーズに適しており、Ajaxを使用して、ユーザーBがまだ素晴らしいエントリを入力するのに忙しい間に更新されたものの差分へのリンクを含む正確な投稿を表示できる場合
Ravi(および他の人)が言ったように、AJAXアプローチを使用して、別の変更が進行中のときにユーザーに通知することができます。編集が送信されたら、テキストの違いを示して、2番目のユーザーに2つのバージョンをマージする方法を考えさせます。
しかし、私はあなたがそれに加えて試すことができる何か新しいものを追加したいと思います:編集者が編集を行っている間に、編集者間のチャットダイアログを開きます。たとえば、埋め込み Gabbly などを使用できます。
 
 
最善の競合解決は直接対話です、と私は言います。
オプティミスティック同時実行制御を使用すると、問題(更新の喪失)を最適に解決できます。
>1つの実装は、システムの編集可能な各エンティティにバージョン列を追加することです。ユーザー編集で行をロードし、ユーザーにhtmlフォームを表示します。非表示フィールドにバージョンが表示されます。たとえば、 3 としましょう。更新クエリは次のようにする必要があります。
update articles set ..., version=4 where id=14 and version=3;
返された行が0の場合、誰かが既に記事14を更新しています。その場合、必要なのは状況への対処方法だけです。一般的な解決策:
- 最後のコミットが勝ちます
- 最初のコミットが勝ちます
- 競合する更新をマージする
- ユーザーに決定させる
増分/ バージョン int / longの代わりに、タイムスタンプを使用できますが、次の理由で推奨されません:
JVMから現在の時刻を取得することは、ノードが時刻同期されていないクラスター環境では必ずしも安全ではありません。
( Java Persistence with Persistence からの引用)
hibernate documentation に詳細情報があります。 。
私のオフィスでは、すべてのデータテーブルに4つのフィールドが含まれるというポリシーがあります:
- CreatedBy
- CreatedDate
- LastUpdateBy
- LastUpdateDate
その方法では、少なくとも最近まで、誰がレコードに対して何をしたかについての素晴らしい監査証跡があります。
しかし、最も重要なことは、画面上の現在のレコードまたは編集されたレコードのLastUpdateDateをページのCookieなどにデータベースの値と保存する必要があることです。一致しない場合は、そこから何をするかを決定できます。