为什么没有.with_lock像我期望的那样工作?

时间:2017-05-11 20:23:08

标签: ruby-on-rails multithreading activerecord locking

我希望下面的代码强制独占访问代码块,但它不是。在我的测试中,每个线程都能够同时运行块。

假设Rails环境和用户是activerecord对象。另请注意,这是我为了解决我遇到Web请求时遇到的并发问题而进行的一项任意测试。

user = User.first
threads = []

3.times do |i|
    threads << Thread.new do
        user.with_lock do
            puts "start: #{i}"
            sleep 1
            puts "stop: #{1}"
        end
    end
end

threads.each(&:join)

预期产出:

start: 1
stop: 1
start: 2
stop: 2
start: 3
stop: 3

实际输出:

start: 1
start: 2
start: 3
stop: 1
stop: 2
stop: 3

我错过了什么? rails .with_lock在标准ruby线程中不起作用吗?或者,这可能是由于我的测试环境使用sqlite3?

2 个答案:

答案 0 :(得分:1)

你显然已经明白了这一点,但要澄清其他人遇到这个问题:

Sqlite3不支持行级锁定。因此,在构建查询时,Arel会忽略任何锁定:

https://github.com/rails/arel/blob/master/lib/arel/visitors/sqlite.rb#L7

答案 1 :(得分:0)

它似乎与sqlite3有关。