J2EE アプリのサイト間でデータを複製する
質問
まだ作業中の J2EE アプリがあります。Oracle DB上で動作します。ビジネス層は、リッチ クライアント インターフェイスを備えた EJB 2.0 でコーディングされています。
ここで、アプリケーションは複数のサイトにデプロイされます。そして各サイトは新しいアイテム(新しい契約など)を作成することになります。
私たちが実現したいのは、ローカルのものと同じ DB スキーマを使用して、中央の場所の DB に追加されたすべての新しいアイテムを複製することです。
これを達成する最も効果的な方法は何だと思いますか?
作成されたすべての新しいアイテムをシリアル化し、Java Message Service キューを介して統合するためにリモート サイトに送信することを考えました。そのアプローチは良いですか?
また、いくつかの変更が衛星に複製されることになります。
解決
センターとの同期関係は望ましくないカップリングをもたらすと言えます。したがって、あなたの非同期のアイデアは私にはかなり良いように思えます。おそらく、レコードには場所に依存する識別子が含まれているため、異なる場所での新しい契約の作成が衝突することはなく、センターへのレプリケーションでの多少の待ち時間は許容されます。
したがって、単純なケースでは、各場所からセンターへの JMS メッセージを使用するだけです。
このアプローチの良い点は、衛星がセンターのデータベース構造について知る必要さえなく、完全に独立して設計できることです。
変更をセンターからサテライトに複製する必要がある場合、事態はさらに興味深いものになります。大きな問題は、センターでの変更とサテライトでの変更の間で競合が発生する可能性があるかどうかです。
単純なケース:どのデータ項目にも「ホーム」が 1 つあります。たとえば、元の衛星は変更が行われる場所です。または、作成後に変更を加えることができるのはセンターだけです。この場合、センターを「ハブ」として扱うことができ、サテライトに変更を伝播できます。これには単純な JMS が適しています。
もう少し難しいケース:変更はどこからでも行えますが、一度に 1 か所でのみ変更できます。したがって、ロック方式の場合には、厳密な種類を導入できます。私はセンターを所有者として持ち、同期 Web サービスを使用してデータをロックおよび更新する傾向があります。今、私たちは結合していますが、最終的な所有者を得るにはそれが必要です。
かなり複雑なケース:ロックすることなく、誰でもどこでも何かを変更できます。これは一種の「まず行動し、後で謝罪する」アプローチです。私たちは、変更が衝突しないという楽観的なアプローチを採用しています。承認のために変更をセンターに送信すると、センターはオプティミスティック ロックを使用するか、競合しない変更をマージするアプローチを使用できます。私は変更を発信元のキューに入れることでこれを行う傾向がありますが、実際には同期呼び出しによって変更を処理します。したがって、変更の仕様とセンターの可用性を切り離します。一部のより高度なデータベースには、これに役立つ差分/マージ機能があります。
大きな問題は、センターの可用性と競合する変更の可能性をどの程度考慮するかです。多くの場合、狡猾なアプリケーション設計により、競合の可能性が大幅に低減されます。