Transactions 使用RSpec测试并行事务

Transactions 使用RSpec测试并行事务,transactions,rspec2,Transactions,Rspec2,有没有办法使用RSpec测试并行事务? 说我有一个银行账户余额,需要在交易中锁定,然后才能减少或增加。 然而,目前,尽管我已经关闭了RSpectransactional\u fixtures选项,但我无法在两个单独的线程中启动两个并行事务。由于某种原因,两者都被绞死了。 给定帐户是一个模型 然后此规范将挂起: it "should ensure operations are performed correctly" do @account = Account.create(:balance

有没有办法使用RSpec测试并行事务? 说我有一个银行账户余额,需要在交易中锁定,然后才能减少或增加。 然而,目前,尽管我已经关闭了RSpec
transactional\u fixtures
选项,但我无法在两个单独的线程中启动两个并行事务。由于某种原因,两者都被绞死了。 给定帐户是一个模型 然后此规范将挂起:

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
it“应确保正确执行操作”是否
@账户=账户。创建(:余额=>0)
线程=[]
(0..1)。每个do |索引|
线程(正确)
账户余额+=100
睡眠0.5
帐户。保存!
结束
结束
结束
线程。每个{t | t.join}
@account.reload.balance.should==200
结束

有没有办法让它不挂起,同时还能展示事务处理的能力?

我想不出一个好的理由来解释为什么您希望在同一资源上有并行、并发的事务。在你的例子中,你到底想要实现什么


在您的代码中,您使用的是同一个实例,因此您可能会陷入死锁。您可能需要重新思考您在这里要做的事情。

我想不出一个好的理由来解释为什么您希望在同一资源上有并行、并发的事务。在你的例子中,你到底想要实现什么


在您的代码中,您使用的是同一个实例,因此您可能会陷入死锁。您可能需要重新思考您在这里要做什么。

您需要在线程中使用不同的数据库连接。首先,断开主线程,然后在每个线程中重新连接,最后在主线程中重新连接,如下所示:

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

线程您需要在线程中使用到数据库的不同连接。首先,断开主线程,然后在每个线程中重新连接,最后在主线程中重新连接,如下所示:

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

线程你是说AR cache my
Account.find()
result?不是。你会遇到死锁,因为这两个事务都在请求(并因此锁定)相同的资源,在本例中是@Account。如果必须以这种方式使用线程,我建议使用互斥类以确保不会出现死锁。(谷歌互斥和线程,你会发现很多例子)。你是说AR cache my
Account.find()
result?不是。你会遇到死锁,因为这两个事务都要求(并因此锁定)相同的资源,在本例中是@Account。如果必须以这种方式使用线程,我建议使用互斥类以确保不会出现死锁。(谷歌互斥和线程,你会发现很多例子)。