Example of something that is not thread-safe in Rails

六月ゝ 毕业季﹏ 提交于 2019-12-03 13:52:07

NOTE
This is only a partial answer since it's a stale read example (which can be caused by both multiprocesses and multithreading), the OP is looking for multithreading issues only it seems.

Here goes, imagine you have a store that sells an item to a user and updates his balance accordingly.

 PaymentsController

    if current_user.balance > item.price 
       current_user.balance = current_user.balance - item.price #1
       current_user.create_purchase(item)  #2
       current_user.save #3
    end

The potential problem here is that inside the condition (lets say in lines #1 or #2) the thread can switch to a different thread, run fully, the balance is now a different value yet when we return to the original thread (still stuck in line #1) it has no idea this has happened! It may allow a purchase for a user with not enough balance and it also override the real balance with a wrong value.

Here's a more concrete example of how this can happen

Let's imagine the user is trying to game our system by buying more than his balance allows him. Item 1 costs 100, Item 2 costs 75 and his balance is 100.

The user writes a script to fire 2 posts requests to purchase these items so they get almost simultaneously to the app server. The first requests hits line #1, and right before line #2 the thread switches to request 2. The second request runs fully with no interruption - it buys the second item so the new real balance is now 25 (100 - 75). Now the context switch to request 1. Request 1 does not realize that the real balance is 25 (it still thinks that the user had enough balance to buy the item: remember that request 1 switched at line #2, inside the condition! Request 1 completes the purchase and then updates the balance to be 0 (100 - 100). The user just bought two products that cost more than his balance should allow!

A way to handle this situation is locking http://api.rubyonrails.org/classes/ActiveRecord/Locking/Pessimistic.html

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!