Rails6、 MySql8で先着順の商品購入サイトをつくっています。
同一の商品(item)を複数のユーザーが購入できないようにしています。
購入の際、悲観的ロックをかけて、itemのstatusがavailableのものだけを購入できるようにしています。
もし、ほかのひとが購入などしてしまって、itemのstatusが、availableではなくなった場合は、
else以降で、changedに追加したもともとの値をつかってリセットし、breakしています。
実際には、購入時は、関連テーブルの処理など複雑になりますが、
これを例えば、else以降で、raiseでロールバックを起こして、処理をリセットさせるほうが
コードを書く際は簡単なのですが、これは行わない方がよいでしょうか。
確か処理が遅くなるという記述をどこかでみたような気がするのですが、
よろしくお願いいたします。
ruby
1def update_items(item_ids:) 2 changed = [] 3 results = { success: true, count: 0, price: 0 } 4 Item.transaction do 5 item_ids.each do |item_id| 6 item = Item.lock.find(item_id) 7 if item.status == "available" 8 changed << ticket.dup 9 results[:count] += 1 10 results[:price] += t.price 11 item.update!(status: "purchased") 12 else 13 changed.each do |c| 14 item = Item.lock.find(c.id) 15 item.update!(status: c.status) 16 end 17 results[:success] = false 18 break 19 end 20 end 21 end 22 results 23end
回答1件
あなたの回答
tips
プレビュー
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2021/09/01 04:11 編集
2021/09/01 04:12 編集