私はRails 3.1とMySQL 5.1を使ってオークションのようなオークションを設計しています。ユーザーには勘定残高があるため、資金が不足しているとオークションアイテムに入札しないことが重要です。オークション/銀行のようなアプリケーション(Rails/MySQL)の楽観的または悲観的なロック
トランザクション1:
もちろん、私は、トランザクションにオークションの「勝利」梱包されますが、このようなものになりところで
ActiveRecord::Base.transaction do
a = Account.where(:id=>session[:user_id]).first
# now comes a long part of code with various calculations and other table updates, i.e. time pases
a.balance -= the_price_of_the_item
a.save!
end
を、私はcurerntlyしたがって、楽観的ロックを使用しています私のテーブルにはすべてlock_versionという列があります。そのようなトランザクションが実行されている間、彼らは入札、コードチェックのピースを置くたびに
は、ユーザが別の入力場所を介して他の入札、従って現在利用可能な残高が再びここで
同じで十分であることができれば:
トランザクション2:
ActiveRecord::Base.transaction do
a = Account.where(:id=>session[:user_id]).first
raise ActiveRecord::Rollback if a.balance < the_price_of_the_bid + Bids.get_total_bid_value_for_user(session[:user_id])
# now process the bid saving
end
はもちろん、私は、トランザクション1が処理中であると私はウィットに終わる一方、そうでない場合は、トランザクション2がバランスを読んだことがあり、2つのトランザクションが重複しないことを、確認する必要がありますh負の口座残高(入札が保存された後、取引1がコミットした後、ユーザーはおそらく自分が持っていない資金で入札する可能性があります)。
注意すべき点は、トランザクション2はアカウントを変更せず、アカウントを読み取るだけであることです。トランザクション1の実行中に選択されたSELECT文の読み込みを防ぐ方法を教えてください。
トランザクション1を完了するためにトランザクション2を待機させるにはどうすればよいですか?オプティミスティックロックと利用可能なMySQLトランザクション分離レベルのいずれかが可能か、ここで悲観的ロックを使用する必要がありますか?暗示的なロックが唯一の答えである場合は、 a.lockを追加します。 2つの取引のそれぞれの口座レコードを読んだ後に で十分でしょうか?私はそれがより コーディングを意味していても、最もパフォーマンスの高いソリューションを探しています
-
デザインのcriteriasはもちろんです。
- データの整合性が最も重要である今の支出を持っ
あなたのデータを理解しようとしています。誰かが10の残高を持っているとします。彼らは10の2つの入札を作成することができます(この時点で、いずれかまたはいずれかが勝つかどうかわかりません)。彼らができない場合、これをどのように追跡していますか? –
いいえ、私は彼らが両方の入札を獲得し、そのアカウントの残高が-10になるリスクがあります。トラッキングは取引2で行われ、使用可能な残高があるかどうかを確認し、ユーザーの口座に十分な金額があれば、入札が承認され、保存されます。 – KKK
このコードでは、現在開いている入札があるかどうかもチェックされます。 (または勘定残高に反映されますか?) –