Rspec 测试模型是不是被锁定以进行更新?
Posted
技术标签:
【中文标题】Rspec 测试模型是不是被锁定以进行更新?【英文标题】:Rspec test for whether a model was locked for updating?Rspec 测试模型是否被锁定以进行更新? 【发布时间】:2022-01-17 06:03:17 【问题描述】:我想知道是否有特定的 rspec 测试可以验证模型是否被悲观锁定以进行更新。您可以检查模型是否已更改,或者获取以前的值,但无论如何,如果模型被锁定以进行更新,是否可以使用活动记录来确定是否在相关操作期间的某个时间点?
【问题讨论】:
【参考方案1】:在我看来,没有办法测试一个模型是否被Locking::Pessimistic
锁定,因为它实际上是database row level lock
,例如FOR UPDATE
,而且Rails 不会知道在数据库级别发生了什么。
例如,当您调用p = Product.lock.find(1)
时,这将执行数据库查询SELECT ... FOR UPDATE
并且不会缓存有关该查询的任何内容(锁或其他任何内容),因此这里的对象 p 只不过是 Product 模型的一个实例。数据库会处理所有的锁机制(其他事务将被阻塞,直到当前事务结束),此时 Rails 什么也不做。
但是,当 Rails 生成查询 SELECT ... FOR UPDATE
时,Rails 使用 ActiveRecord::Relation#lock
方法,因此您可以通过测试查询该模型的关系来测试模型实例是否被锁定。
x = Product.lock # Relation
x.locked? # true
s = x.find(1)
s.locked? # undefined method
# test that the Product call `:lock`
expect(Product).to receive(:lock)
# test that a Product Relation call `:lock`
expect_any_instance_of(ActiveRecord::Relation).to receive(:lock)
Product.where(id: 1).lock.all
【讨论】:
以上是关于Rspec 测试模型是不是被锁定以进行更新?的主要内容,如果未能解决你的问题,请参考以下文章