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 测试模型是不是被锁定以进行更新?的主要内容,如果未能解决你的问题,请参考以下文章

RSpec 测试失败 - 使用显示套接字但缺少锁定文件

锁定特定文档以在Solr中进行编辑

如何判断一行是不是被锁定?

Teradata 7423:HY000] 对象已锁定,现在等待。交易中止

怎么查看mysql表是不是被锁定

Project Server调用PSI关闭任务以进行更新锁定任务