4

假设我在网上书店的数据模型看起来像这样:

在此处输入图像描述

在创建新订单之前,我想确保有足够的商品库存,所以我有这样的方法

def ensure_enough_in_stock
    errors.add(:quantity, "not enough in stock") if quantity > book.stock
end

为了确保在保存到数据库之前调用此方法,我使用了验证:

validate :ensure_enough_in_stock, :on => create

总而言之,当我创建订单时:

  1. 验证方法被称为
  2. 新订单被写入数据库(如果验证通过)

如果在 1. 和 2. 之间,另一个进程(一个并发访问,另一个线程,...)对同一本书的 stock 属性进行了修改,会发生什么?是否引发了异常?

更一般地说,如何处理在验证和保存到数据库之间发生的情况?

我认为我也应该在数据库中进行验证,但我不知道它会对性能产生什么影响。有没有聪明的方法来处理这种情况?

编辑

按照此处的说明锁定交易可以防止对股票的写访问,但是如果我在 Book 模型中也有一个“已发布”属性,它可以采用“公共”或“私有”值,然后我想确保你不能买一本私人的书。

但是,与股票值可以通过外部进程更改相同的方式,发布的值也可以更改:在这种情况下,锁定不会有任何帮助,不是吗?

在此处输入图像描述

4

1 回答 1

2

Rails 通常将验证和保存包装在事务中。因此,您唯一需要做的就是使用 lock in 运行查询ensure_enough_in_stock。锁将防止数据被其他请求更改。请参阅this了解如何使用锁定进行查询。

于 2012-11-07T12:05:14.837 回答