我希望下面的代码强制独占访问代码块,但它不是。在我的测试中,每个线程都能够同时运行块。
假设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?
答案 0 :(得分:1)
你显然已经明白了这一点,但要澄清其他人遇到这个问题:
Sqlite3不支持行级锁定。因此,在构建查询时,Arel会忽略任何锁定:
https://github.com/rails/arel/blob/master/lib/arel/visitors/sqlite.rb#L7
答案 1 :(得分:0)
它似乎与sqlite3有关。