9

ウィキ スタイルの Web サイトで、書き込みと書き込みの競合を防止または軽減しながら、サイトを高速に実行し、サイトの使いやすさを維持するにはどうすればよいですか?

私が予見する問題はこれです:

  1. ユーザー A がファイルの編集を開始する
  2. ユーザー B がファイルの編集を開始する
  3. ユーザー A がファイルの編集を終了する
  4. ユーザー B がファイルの編集を終了し、誤ってユーザー A の編集内容をすべて上書きしてしまう

ここに私が思いついたいくつかのアプローチがあります:

  • ある種のチェックアウト/チェックイン/ロック システムを用意します (ただし、人々がファイルを「長時間」チェックアウトしたままにしないようにする方法はわかりません。許可されていないことでユーザーがイライラすることは望ましくありませ編集します)
  • ユーザーが変更をコミットしたときに行われた他の変更を表示し、何らかのマージを許可する何らかの差分システムを用意します (ただし、これを作成するのが難しく、サイトを使用するのが「難しすぎる」のではないかと心配しています)。
  • ユーザーが変更を行っているに同時編集を通知する (ある種の AJAX?)

これに行く他の方法はありますか?これをうまく実装しているサイトの例はありますか?

4

8 に答える 8

17

最後の変更のバージョン番号 (または ID) を覚えておいてください。次に、エントリを書き込む前に読み取り、このバージョンがまだ同じかどうかを比較します。

競合が発生した場合は、その間に変更されたエントリを書き込もうとしていたユーザーに通知します。差分で彼をサポートします。

ほとんどのウィキはこのようにしています。MediaWikiUsemodなど。_

于 2009-03-08T20:04:57.563 に答える
4

Mediawiki では、サーバーが最初の変更を受け入れ、2 番目の編集が保存されると競合ページが表示され、2 番目の人が 2 つの変更をマージします。ウィキペディア: Help:Edit Conflictsを参照してください。

于 2009-03-09T03:10:14.217 に答える
1

Ravi (および他の人) が言ったように、AJAX アプローチを使用して、別の変更が進行中のときにユーザーに通知することができます。編集が送信されたら、テキストの違いを示すだけで、2 番目のユーザーに 2 つのバージョンをマージする方法を考えてもらいます。

しかし、それに加えて、あなたが試すことができる何か新しいことを追加したいと思います: 編集者が編集している間に、編集者間のチャット ダイアログを開きます。たとえば、そのために埋め込まれたGabblyのようなものを使用できます。
 
 
最善の紛争解決策は、直接対話することだと私は言います。

于 2009-03-15T22:12:50.080 に答える
1

Gmail では、メールへの返信を書いていて、まだ入力中に他の誰かが返信を送信すると、新しい更新があることを示すポップアップが表示され、更新自体がページのリロードなしで別の投稿として表示されます。このアプローチはあなたのニーズに合っています.Ajaxを使用して、更新されたばかりの差分へのリンクを含む正確な投稿を表示できれば、ユーザーBはまだエントリを入力するのに忙しいです.

于 2009-03-15T15:59:19.043 に答える
1

おそらく、ロック機構を使用するのが最も簡単に実装できます。各記事には、それに関連付けられたロック フィールドとロック時間があります。ロック時間が設定値を超えた場合は、ロックが無効であると見なし、編集のために記事をチェックアウトするときにロックを解除します。開いているロックを追跡し、セッションを閉じるときにそれらを削除することもできます。また、2 人のユーザーが編集できた場合に備えて、チェックアウトしたバージョンへの更新をチェックインしていることを確認できるように、データベースにいくつかの同時実行制御 (おそらく自動生成されたタイムスタンプ) を実装する必要があります。同時に記事。正しいバージョンを持つものだけが、編集を正常にチェックインできます。

違いを構築するためだけに使用できる差分エンジンを見つけることもできますが、wiki エディターでそれらを表示するのは問題があるかもしれません。実際に違いを表示することは、おそらく差分を構築するより難しいでしょう。編集を拒否して差分を実行する必要がある場合は、バージョン管理システムに依存して検出します。

于 2009-03-08T20:07:06.090 に答える
0

問題 (失われた更新) は、Optimistic Concurrency Controlを使用して最もよく解決されます。

1 つの実装は、システムの編集可能な各エンティティにバージョン列を追加することです。ユーザーの編集時に、行をロードし、ユーザーに html フォームを表示します。隠しフィールドはバージョンを示します。たとえば、 3としましょう。更新クエリは次のようにする必要があります。

update articles set ..., version=4 where id=14 and version=3;

返された行数が 0 の場合、誰かが既に記事 14 を更新しています。その場合に必要なのは、その状況にどう対処するかだけです。いくつかの一般的な解決策:

  1. 最後のコミットが勝つ
  2. 最初のコミットが勝つ
  3. 競合する更新をマージする
  4. ユーザーに決めさせる

インクリメントバージョンの int/long の代わりにタイムスタンプを使用できますが、次の理由から推奨されません。

JVM から現在の時刻を取得することは、ノードが時刻同期されていない可能性があるクラスター環境では必ずしも安全ではありません。

( Java Persistence with Hibernateからの引用)

hibernate documentationの詳細情報。

于 2009-03-12T20:38:29.730 に答える