3

ユーザーが予約する座席はほとんどありません。一度に予約手続きに参加できるのは1人のユーザーのみで、複数のユーザーが同じ座席を予約することはありません。私のJavaコードでは、「同期」キーワードを使用してそれを実現しました。これは機能します。

ただし、現在、私のコードは S1 と S2 などの 2 つのサーバーにデプロイされています。仮説として、空席があるとしましょう。U1 と U2 という 2 人のユーザーが、最後の座席を予約したいと考えています。ロード バランサーがユーザー U1 をサーバー S1 に、ユーザー U2 をサーバー S2 に送信する場合があります。現在、「ローカル」同期は同じように機能しますが、予約中に他のユーザーをブロックすることはできません。これにより、両方のユーザーが最後の座席を予約することになり、問題が発生します。

問題は、複数のサーバー環境で競合することなく複数のユーザーが座席を予約できるようにするにはどうすればよいかということです。

4

2 に答える 2

3

言語レベルで行うのは難しいです。一部の分散キャッシュが役立つ場合があります。たとえば、Terracottaはクラスター化された環境で同期キーワードを処理しますが、試したことはなく、確かにパフォーマンスが低下します。あなたの場合のように、インスタンスを重要な時間待機させることに非常に注意します。

それ以外の場合は、分散 JNDI、分散シングルトン、またはサーバー インスタンスが通信し、プロセス中にそれを確認するために行われる同様の処理が役立つ可能性があります。

しかし、この問題は実際には楽観的ロックを行うことで通常回避されます。これは、異常な / ありそうにない瞬間にのみ発生すると単純に想定して、1 つのインスタンスの場合のように処理することもできます。そして、うまくいかないときの対処法を考えてみましょう。これはよりビジネス ロジックのシナリオになり、それを行う最善の方法は、ユーザーが不満を抱く可能性を最小限に抑える方法を見つけることです。

通常、永続化/データベース レベルで一貫性が保証されているため、そこに書き留めておくとよいでしょう。メモリリークやその他のリソースの枯渇を要求するため、数分以上保持している可能性のあるインスタンスをブロックするために synchronized キーワードを使用することは絶対にありません。

個人的には、これを扱う JPA/Hibernate を使用するときにL2 キャッシュを使用するのが好きです。OpenJPA には、エンティティーが変更され、L1 キャッシュからそれを取り消す必要があることを他のインスタンスに通知するだけの場合に、L2 処理を実行するためのパフォーマンス フレンドリーな方法があります。これは、同期されたJava言語キーワードを使用して「同期」するよりも、あなたのケースでははるかに優れたアプローチかもしれません。

私の経験では多くのアプリケーションで無視されているため、対処方法を考えるのはあなたの側で良い態度です. ビジネス志向のマネージャーにとって、なぜ投資すべきかを理解するのが難しい、可能性の低いシナリオになることがあまりにも多い.

于 2013-02-19T01:31:03.323 に答える
2

基本的に、分散システムが通信できる方法は 4 つあります。

  1. 共有データベース。
  2. リモート プロシージャ コール
  3. メッセージング。
  4. 共有ファイル システム。

共有データベースのアプローチを検討してください。. 大規模なスケーリングが必要ない場合は、リレーショナル データベースを使用するのが最も簡単です。これは、ほぼすべてのデータベースがある程度の ACID (原子性、一貫性、分離、耐久性) を提供するためです。. .

トランザクションを設定し、衝突が発生した場合にロールバック/ハンドルすることができます。これは楽観的ロック戦略と呼ばれます。

Spring + JPA/Hibernate を使用する場合、面倒な作業はすべて完了しており、更新メソッドに @Transactional アノテーションを追加するだけです。. . 春に関する素晴らしい本は "Spring in Action" です。

もう 1 つのオプションは、分散キャッシュを使用することです。

于 2013-02-19T01:07:27.593 に答える