2011-01-13 72 views
1

有沒有什麼方法可以使用RSpec來測試並行事務? 說我有一個銀行賬戶餘額,需要在一個交易中被鎖定,然後它被減少或增加。 但是,目前,雖然我關閉了RSpec transactional_fixtures選項,但我無法在兩個分離的線程中啓動2個並行事務。出於某種原因,兩者都被掛起。 定帳戶的模型 然後這個規範將掛起:使用RSpec測試並行事務

it "should ensure operations are performed correctly" do 
    @account = Account.create(:balance => 0) 
    threads = [] 
    (0..1).each do |index| 
    threads << Thread.new do 
     Account.transaction do 
     account = Account.find(@account.id, :lock => true) 
     account.balance += 100 
     sleep 0.5 
     account.save! 
     end 
    end 
    end 
    threads.each{|t|t.join} 
    @account.reload.balance.should == 200 
end 

有沒有什麼辦法讓它不掛,同時仍然能夠證明交易的能力嗎?

回答

0

我想不出一個很好的理由,爲什麼你想要在同一個資源上進行並行事務。你在你的例子中究竟想達到什麼目的?

在您的代碼中,您使用的是同一個實例,因此預計會陷入死鎖。你可能想要重新考慮你想在這裏做什麼。

+0

你是說AR緩存我的`Account.find()`結果嗎? – 2011-04-03 02:17:28

1

您需要在線程中使用不同的數據庫連接。首先,斷開主線程,然後重新連接在每個線程,終於重新連接主,像這樣:

ActiveRecord::Base.connection.disconnect! 
(0..1).each do |index| 
    threads << Thread.new do 
    ActiveRecord::Base.establish_connection 
    # ... 
    end 
end 
ActiveRecord::Base.establish_connection 

有在測試這樣的其他問題:你有沒有在那裏併發發生點的保證。紅寶石GIL也無濟於事。你應該使用fork來代替線程,或者使用fork_break gem:https://github.com/remen/fork_break