サーバーから大量のデータを表示するWebページがあります。通信はajax経由で行われます。
ユーザーがこのデータを操作および変更するたびに(ユーザーAが名前を変更すると)、サーバーにアクションを実行するよう指示し、サーバーは新しい変更されたデータを返します。
ユーザーBが同時にページにアクセスして新しいデータオブジェクトを作成すると、ajaxを介してサーバーに再度通知され、サーバーはユーザーの新しいオブジェクトを返します。
Aのページには、オブジェクトの名前が変更されたデータがあります。 Bのページには、新しいオブジェクトのデータがあります。サーバーでは、データの名前が変更されたオブジェクトと新しいオブジェクトの両方があります。
複数のユーザーが同時にページを使用しているときに、ページをサーバーと同期させるためのオプションは何ですか?
すべての変更でページ全体をロックしたり、状態全体をユーザーにダンプしたりするようなオプションは避けられます。
それが役立つ場合、この特定の例では、Webページはデータベースでストアドプロシージャを実行する静的Webメソッドを呼び出します。ストアドプロシージャは、変更されたデータを返します。次に、静的Webメソッドは、ストアドプロシージャの戻り値をクライアントに転送します。
バウンティ編集:
Ajaxを使用してサーバーと通信し、同時実行の問題を回避するマルチユーザーWebアプリケーションをどのように設計しますか?
つまりデータや状態の破損のリスクなしに、データベース上の機能とデータに同時にアクセスする
概要:
こんにちはRaynos、
ここでは特定の製品については説明しません。他の人が言及したのは、すでに調べておくのに適したツールセットです(おそらくnode.jsをそのリストに追加してください)。
アーキテクチャの観点から見ると、バージョン管理ソフトウェアで見られる問題と同じ問題があるようです。 1人のユーザーがオブジェクトの変更をチェックインし、別のユーザーが別の方法で同じオブジェクトを変更したい場合=>競合。ユーザーの変更をオブジェクトに統合すると同時に、更新をタイムリーかつ効率的に配信し、上記のような競合を検出して解決する必要があります。
私があなたの靴にいたなら、私はこのようなものを開発します:
私が「アトミックアーティファクト」と呼ぶもの(ページ?ページ上のオブジェクト?オブジェクト内の値?)を定義する合理的なレベルを決定します。これは、ウェブサーバー、データベースとキャッシングハードウェア、ユーザー数、オブジェクト数などに依存します。簡単な決定ではありません。
各アトミックアーティファクトには次のものがあります。
接続されたユーザーに関連する変更ログを効率的に配信できるサーバーまたは擬似サーバーコンポーネント。 Observer-Patternはあなたの友人です。
上記のサーバーへの長時間実行HTTP接続を使用できる、または軽量ポーリングを使用するjavascriptクライアント。
接続されたjavascriptクライアントが監視対象の成果物履歴の変更を通知したときにサイトのコンテンツを更新するjavascript成果物アップデータコンポーネント。 (再びオブザーバーパターンが良い選択かもしれません)
ミューテックスロックを取得しようとして、アトミックアーティファクトの変更を要求する可能性があるjavascriptアーティファクトコミッターコンポーネント。既知のクライアント側のartifact-version-idと現在のサーバー側のartifact-version-idを比較することにより、アーティファクトの状態が数秒前に別のユーザーによって変更されたかどうかを検出します(javascriptクライアントのレイテンシーとコミットプロセス要因)。
人間が正しい変更を決定できるようにするjavascript競合ソルバー。 「誰かがあなたよりも速かったです。変更を削除しました。泣きます。」とユーザーに伝えたくないかもしれません。かなり技術的な差分や、よりユーザーフレンドリーなソリューションからの多くのオプションが考えられます。
それでは、どのように転がりますか...
これがあなた自身のアイデアの出発点になることを願っています。もっと多くの可能性があると確信しています。この投稿に対する批判や機能強化を歓迎している以上、wikiは有効になっています。
クリストフ・ストラセン
これは古い質問であることは知っていますが、私はただチャイムインしたいと思っていました。
OT(operational transforms) は、同時かつ一貫したマルチユーザー編集の要件に適しているようです。 Googleドキュメントで使用される技術 (およびGoogle Waveでも使用されます):
Operational Transforms-ShareJS( http://sharejs.org/ )を使用するためのJSベースのライブラリがあります。これは、Google Waveチームのメンバーによって作成されました。
また、必要に応じて、完全なMVC Webフレームワーク-DerbyJS( http://derbyjs.com/ )がShareJS上に構築されており、すべて自動で実行されます。
サーバーとクライアント間の通信にBrowserChannelを使用します(WebSocketのサポートは機能しているはずです-以前はSocket.IOを介して行われていましたが、Socket.ioの開発者の問題のために削除されました)。ただし、現時点ではビットがまばらです。
各データセットに時間ベースの修正スタンプを追加することを検討します。したがって、dbテーブルを更新する場合は、それに応じて変更されたタイムスタンプを変更します。 AJAXを使用すると、クライアントの変更されたタイムスタンプとデータソースのタイムスタンプを比較できます。ユーザーが遅れている場合は、表示を更新します。このサイトが質問を定期的にチェックして、回答の入力中に他の人が回答したかどうかを確認する方法と同様です。
プッシュ技術(CometまたはリバースAjaxとも呼ばれます)を使用して、dbに加えられた変更をすぐにユーザーに伝達する必要があります。現在これに利用できる最良の手法はAjaxロングポーリングのようですが、すべてのブラウザーでサポートされているわけではないため、フォールバックが必要です。幸いなことに、すでにこれを処理するソリューションがあります。その中には、orbited.orgと既に述べたsocket.ioがあります。
将来、WebSocketsと呼ばれるこれを行う簡単な方法がありますが、標準の現在の状態に関するセキュリティ上の懸念があるため、いつその標準がプライムタイムの準備が整うかはまだわかりません。
新しいオブジェクトを使用したデータベースに同時実行性の問題があってはなりません。ただし、ユーザーがオブジェクトを編集する場合、サーバーには、その間にオブジェクトが編集または削除されたかどうかを確認するロジックが必要です。オブジェクトが削除されている場合、ソリューションは単純です。編集を破棄するだけです。
しかし、複数のユーザーが同じオブジェクトを同時に編集している場合、最も難しい問題が発生します。ユーザー1と2が同時にオブジェクトの編集を開始すると、両方が同じデータで編集を行います。ユーザー2がまだデータを編集している間に、ユーザー1が行った変更が最初にサーバーに送信されたとします。次に、2つのオプションがあります:ユーザー1の変更をユーザー2のデータにマージするか、データが古いことをユーザー2に伝え、データがサーバーに送信されるとすぐにエラーメッセージを表示することができます。後者はここではあまりユーザーフレンドリーなオプションではありませんが、前者は実装が非常に困難です。
初めてこれを正しく実現した数少ない実装の1つは EtherPad で、これはGoogleによって買収されました。その後、彼らはGoogle DocsとGoogle WaveでEtherPadの技術のいくつかを使用したと思いますが、確かにそれを伝えることはできません。 GoogleはEtherPadもオープンソース化したので、何をしようとしているのかにもよりますが、一見の価値があります。
これを同時に編集するのは本当に簡単なことではありません。なぜなら、遅延のためにウェブ上でアトミックな操作を行うことができないからです。多分 この記事 は、このトピックについてさらに学ぶのに役立ちます。
これらすべてを自分で書き込もうとするのは大きな仕事であり、それを正しく行うことは非常に困難です。 1つのオプションは、クライアントをデータベースと、およびリアルタイムで相互に同期させるために構築されたフレームワークを使用することです。
Meteorフレームワークがこれをうまく行うことがわかりました( http://docs.meteor.com/#reactivity )。
「Meteorはリアクティブプログラミングの概念を採用しています。つまり、単純な命令型スタイルでコードを記述でき、コードが依存するデータが変更されるたびに結果が自動的に再計算されます。」
「この単純なパターン(リアクティブな計算+リアクティブなデータソース)には幅広い適用性があります。プログラマーは、サブスクライブ/リサブスクライブコールを記述し、適切なタイミングで呼び出されるようにすることで節約されます。エラーが発生しやすいロジックを備えたアプリケーション。」
流星 について誰も言及していないとは信じられません。確かに新しい未熟なフレームワークです(そして公式に1つのDBのみをサポートします)が、all単調な作業とマルチユーザーの思考を取りますポスターのようなアプリが説明しています。実際、マルチユーザーのライブ更新アプリを構築することはできません。以下に簡単な要約を示します。
Meteorは非常に単純なので、少なくともアイデアを盗むためにそれを見てみるとよいでしょう。
これらのウィキペディアのページは、 並行性 および 並行計算 の学習に視点を追加するのに役立ちます ajaxウェブアプリケーションプル または プッシュ 状態 イベント ( [〜#〜] eda [〜#〜] ) メッセージメッセージングパターン 基本的に、メッセージは変更イベントおよび同期要求に応答するチャネルサブスクライバーに複製されます。
同時ウェブベースの多くの形式があります 共同ソフトウェア 。
多くの etherpad-liteのHTTP APIクライアントライブラリ 、a 共同リアルタイムエディター があります。
Django-realtime-playground は、 Socket.io などのさまざまなリアルタイムテクノロジーを使用して、Djangoにリアルタイムチャットアプリを実装します。
AppEngineとAppScaleの両方が AppEngine Channel API ;を実装します Google Realtime API とは異なります。これは googledrive/realtime-playground で示されています。