Testing parallel transactions using RSpec

风格不统一 提交于 2019-12-11 05:22:53

问题


Is there any way to test parallel transaction using RSpec? Saying I have a bank account balance that need to be locked inside a transaction before it is decreased or increased. However, currently, although I have turned off RSpec transactional_fixtures option, I cannot launch 2 parallel transaction in two separated threads. For some reason, both are hung. Given Account is a model Then this spec will hang:

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

Is there any way to make it not hang while still be able to demonstrate the ability of transaction?


回答1:


You need to use different connections to the database in your threads. First, disconnect the main thread, then reconnect in each thread, and finally reconnect in the main, like so:

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

There are other problems in testing that way: You have no guarantee of the point where concurrency happens. The ruby GIL will also not help. You should use forks instead of threads, or use the fork_break gem: https://github.com/remen/fork_break




回答2:


I cannot think of a good reason why you'd want to have parallel, concurrent transactions on the same resource. What exactly are you trying to achieve in your example?

In your code you're using the same instance so the fact that you're getting yourself into a deadlock is expected. You probably want to re-think what you're trying to do here.



来源:https://stackoverflow.com/questions/4682575/testing-parallel-transactions-using-rspec

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!