Reputation: 710
Let's say I have on online book store whose data model lookes like that:
Prior to creating a new order, I want to make sure that enough items are in stock, so I have a method like this
def ensure_enough_in_stock
errors.add(:quantity, "not enough in stock") if quantity > book.stock
end
To make sure that this method is called prior to saving in the database, I use a validate:
validate :ensure_enough_in_stock, :on => create
So to sum things up, when I create an order:
What happens if between 1. and 2., another process (a concurrent access, another thread, ...) performs a modification on the stock attribute of the same book? Is the exception raised or not?
More generally, how to deal with the cases where something happens between validation and saving to the database?
I think that I should put a validation into the database as well, but I don't know what impact it would have on performance. Is there a clever way to deal with this kind of situation?
EDIT
Locking the transactions as explained here prevents write access to stock, but what happens if I also have a "published" attribute in the Book model, that can take the values "public" or "private", and then I want to make sure that you can't buy a book that's private.
But the same way that the stock value could be changed by an external process, the published value can be changed as well: in this case the locking would not be of any help, would it?
Upvotes: 4
Views: 2442