アプリケーション
やあ、
複数のユーザーが共通のエンティティに対してアクションを実行するアプリケーション (J2EE/Hibernate/JPA) があります。
簡単にするために、このアプリケーションがGoogle docsのようなものだとしましょう。多くのユーザーが同時に更新できる共有ドキュメントです。
並行性を処理するためにオプトミスティック ロックを選択しました。
- 文は別個の実体です
- 複数のユーザーが同時に同じ文章を更新する可能性は低い
- その場合、いずれかのユーザーに「別のユーザーが同じ文章を編集しようとして申し訳ありません」というメッセージが表示されれば問題ありません。
バックグラウンド プロセス
ここまでは順調ですね。
しかし今、このアプリケーションにバックグラウンド プロセス(非常に高速なもの) を追加しました。彼らは定期的に変更を加えます(単語の出現を別の単語に置き換えるとしましょう)。
それらのジョブは失敗しても問題ありません。彼らのタスクは緊急ではなく、次回 (10 秒後) に同じタスクを試すことができます。
このような状況での楽観的ロックの問題は、1 人のユーザーがドキュメント全体に対してこれ以上長いアクションを実行できなくなることです。
実際、ユーザーがドキュメント全体 (すべての文) のフォントを変更し、このアクションにしばらく時間がかかる場合 (> 10 秒)、その間にバックグラウンド プロセスがいくつかの単語を変更し、より長いアクション (= ユーザーaction : change font) は同時アクセスで失敗します。
これは、ユーザーに次のメッセージを表示することはできません: 「いくつかの技術的なプロセスが同時に実行されていたため、アクションは失敗しました」
また、バックグラウンド プロセスは後で再試行できるため、むしろ失敗させます。
質問
楽観的ロックアプローチの中で、一部のアクション/アクターに対して悲観的ロックを設定するにはどうすればよいですか?
考えられる解決策
ユーザーにとって楽観的なアプローチを維持するために、次の解決策を考えました。
- 「ユーザー アクション」フラグを作成します。これは、任意のユーザーの任意のアクション中に設定されます。
- このフラグが「オフ」になるまで、ジョブは開始されません
- 実行中のプロセスの最後に、フラグがオンになっているかどうかを確認します。オンになっている場合は、このアクションをキャンセル/ロールバックします。
このようにして、ユーザーが何もしていないアイドル時にのみプロセスを実行できます。
ヘルプ
これは良いアプローチですか?ハイブリッド タイプのロックの優れたプラクティスに関する記事や議論は見つかりませんでした。