3

アプリケーション

やあ、

複数のユーザーが共通のエンティティに対してアクションを実行するアプリケーション (J2EE/Hibernate/JPA) があります。

簡単にするために、このアプリケーションがGoogle docsのようなものだとしましょう。多くのユーザーが同時に更新できる共有ドキュメントです。

並行性を処理するためにオプトミスティック ロックを選択しました。

  • 文は別個の実体です
  • 複数のユーザーが同時に同じ文章を更新する可能性は低い
  • その場合、いずれかのユーザーに「別のユーザーが同じ文章を編集しようとして申し訳ありません」というメッセージが表示されれば問題ありません。

バックグラウンド プロセス

ここまでは順調ですね。

しかし今、このアプリケーションにバックグラウンド プロセス(非常に高速なもの) を追加しました。彼らは定期的に変更を加えます(単語の出現を別の単語に置き換えるとしましょう)。

それらのジョブは失敗しても問題ありません。彼らのタスクは緊急ではなく、次回 (10 秒後) に同じタスクを試すことができます。

このような状況での楽観的ロックの問題は、1 人のユーザーがドキュメント全体に対してこれ以上長いアクションを実行できなくなることです。

実際、ユーザーがドキュメント全体 (すべての文) のフォントを変更し、このアクションにしばらく時間がかかる場合 (> 10 秒)、その間にバックグラウンド プロセスがいくつかの単語を変更し、より長いアクション (= ユーザーaction : change font) は同時アクセスで失敗します。

これは、ユーザーに次のメッセージを表示することはできません: 「いくつかの技術的なプロセスが同時に実行されていたため、アクションは失敗しました」

また、バックグラウンド プロセスは後で再試行できるため、むしろ失敗させます。

質問

楽観的ロックアプローチの中で、一部のアクション/アクターに対して悲観的ロックを設定するにはどうすればよいですか?

考えられる解決策

ユーザーにとって楽観的なアプローチを維持するために、次の解決策を考えました。

  • 「ユーザー アクション」フラグを作成します。これは、任意のユーザーの任意のアクション中に設定されます。
  • このフラグが「オフ」になるまで、ジョブは開始されません
  • 実行中のプロセスの最後に、フラグがオンになっているかどうかを確認します。オンになっている場合は、このアクションをキャンセル/ロールバックします。

このようにして、ユーザーが何もしていないアイドル時にのみプロセスを実行できます。

ヘルプ

これは良いアプローチですか?ハイブリッド タイプのロックの優れたプラクティスに関する記事や議論は見つかりませんでした。

4

1 に答える 1

1

「ドキュメント」の場合は、読み書きロックの典型的なケースです。

読み取り/書き込みロックは機能するため、複数のリーダーがリソースを並行してロックできますが、ライターは 1 つだけです。このため、リーダーとライターは相互に排他的です。

実際のユーザーは、編集を開始するときにドキュメントに「読み取り」ロックを設定します。同時に複数のユーザーが入力でき、それぞれが別の文章を編集します。

この場合、バックグラウンド プロセスはライターです。リーダー (および他のライター) がこのドキュメントをロックしていない場合は、(「書き込み」ロックを設定することによって) 入ることができます。その後、バックグラウンド プロセスがその変更を行うことができます。

また、ユーザーがドキュメントを開くのに失敗することもありますが、バックグラウンド プロセスが高速であるため、その可能性はほとんどありません (これは一時的なものであり、ユーザーに通知しなくても 1 秒後に再試行できます)。

参照を提供するために、JPA でLockModeType.READandを使用する方法を次に示します。 JPAでの読み取り/書き込みロックLockModeType.WRITE

于 2014-06-19T13:57:50.337 に答える