5

我有一系列记录要保存为交易的一部分。除了正常的 AR 记录外,我还在进行信用卡网关交易。如果它或 AR 交易失败,我希望一切都回滚......除了我从信用卡网关返回的失败交易的数据(原因、日期等)。就像是

def pay
  Payment.transaction do
    payment.save
    other.save
    result = credit_card.purchase  # this does the gateway transaction, no database stuff
    if result.failure
      raise ActiveRecord::Rollback
      result.save  # this is the part I want to always save
    end
    another.save
  end
end

有没有办法从失败回滚中排除事务中的特定部分?

导轨 3.2.5,MySQL 5.1

4

1 回答 1

13

我不是 100% 确定我理解你为什么要这样做,但你能把信用卡的东西保存在交易之外吗?

result = nil
Payment.transaction do
  payment.save
  other.save
  result = credit_card.purchase  # this does the gateway transaction, no database stuff
  if result.failure
    raise ActiveRecord::Rollback      
  end
end
result.save

(由于块变量作用域的工作方式,您需要在事务之前将结果设置为 nil)

另一种可能的策略是利用事务是在每个连接的基础上完成的这一事实。两个线程将使用不同的连接,所以你可以这样做:

Payment.transaction do
  payment.save
  other.save
  result = Thread.new do
    ActiveRecord::Base.connection_pool.with_connection do
      credit_card.purchase.tap do |result|
        result.save
      end
    end
  end.join.value
  if result.failure 
    raise ActiveRecord::Rollback
  end
end

或者也许只是:

Payment.transaction do
  payment.save
  other.save
  result = credit_card.purchase
  Thread.new do
    ActiveRecord::Base.connection_pool.with_connection do
      result.save
    end
  end.join
  if result.failure 
    raise ActiveRecord::Rollback
  end
end

这里购买发生在另一个线程上,即使用它自己的数据库连接。该线程中发生的任何事情都不会回滚

于 2012-07-13T22:23:19.977 回答