1

有没有办法使用 RSpec 测试并行事务?假设我有一个银行账户余额需要在减少或增加之前锁定在交易中。但是,目前,虽然我关闭了 RSpectransactional_fixtures选项,但我无法在两个单独的线程中启动 2 个并行事务。由于某种原因,两者都被挂起。给定 Account 是一个模型然后这个规范将挂起:

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

有没有办法让它不挂起,同时还能展示交易能力?

4

2 回答 2

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_break gem:https ://github.com/remen/fork_break

于 2013-12-23T12:18:38.200 回答
0

我想不出为什么要在同一资源上进行并行并发事务的充分理由。在您的示例中,您到底想达到什么目的?

在您的代码中,您使用的是相同的实例,因此您会陷入僵局。您可能想重新考虑您要在这里做什么。

于 2011-03-29T15:50:51.317 回答