2017-05-11 6 views
1

以下のコードでは、コードブロック内の排他アクセスを強制することが期待されますが、そうではありません。私のテストでは、各スレッドはブロックを同時に実行することができます。.with_lockが期待どおりに動作しないのはなぜですか?

Rails環境を想定し、userは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 

私は何をしないのですか?レール.with_lockは標準のルビスレッド内で動作しませんか?または、これはおそらく私のテスト環境sqlite3を使用しているためですか?


答えて

0

これはsqlite3に関連しているようです。

0

あなたは明らかにすでにこれを考え出したが、この問題が発生した他人のために明確にする:

sqlite3のは、行レベルのロックをサポートしていません。したがって、Arelはクエリを構築するときにロックを無視します。

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

関連する問題