コントラクトというテーブルがあります。これらの契約記録は、外部サイトのユーザーによって作成され、内部サイトのスタッフによって承認または拒否される必要があります。コントラクトが拒否されると、データベースから削除されます。ただし、受け入れられると、契約受け入れと呼ばれる新しいレコードが生成されます。このレコードは、独自のテーブルに書き込まれ、契約に存在するデータから派生します。
問題は、2人の社内スタッフがそれぞれ同じ契約を結ぶ可能性があることです。最初のユーザーが承諾し、契約承諾レコードが生成されます。次に、同じ契約レコードがページ上で開いたままの状態で、2番目のユーザーが再び契約を受け入れ、重複した受け入れレコードを作成します。
これを乗り越えるための迅速で汚い方法は、受け入れられる直前にデータベースからコントラクトを取得し、ステータスを確認して、すでに受け入れられたことを示すエラーメッセージを生成することです。これはおそらくほとんどの状況で機能しますが、ユーザーはそれでもまったく同時に[同意する]ボタンをクリックして、この検証コードを忍び込むことができます。
また、2つのスレッドが同時に同じコード領域に入るのを防ぐ、データレイヤーの奥深くにあるスレッドロックについても検討しましたが、アプリは2つの負荷分散サーバーに存在するため、ユーザーは別々のサーバーにいる可能性があります。このアプローチを役に立たなくします。
私が考えることができる唯一の方法は、データベースに存在する必要があります。概念的には、ストアドプロシージャまたはテーブルをロックして、同時に2回更新できないようにしたいのですが、ここではOracleについて十分に理解していない可能性があります。アップデートはどのように機能しますか?更新要求がまったく同時に発生しないように、どういうわけかキューに入れられていますか?その場合、SQLでレコードのステータスを確認し、すでに受け入れられていることを示す値をoutパラメーターに返すことができます。ただし、更新要求がキューに入れられていない場合でも、2人がまったく同時に更新SQLにアクセスする可能性があります。
これについて行く方法についての良い提案を探しています。