ruby-on-rails-3 - 即使事务回滚,Rails 也会在事务中保存记录?

标签 ruby-on-rails-3 transactions

我有一系列记录要保存为交易的一部分。除了正常的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

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

Rails 3.2.5,MySQL 5.1

最佳答案

我不是 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

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

关于ruby-on-rails-3 - 即使事务回滚,Rails 也会在事务中保存记录?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11478105/

相关文章:

ruby-on-rails - 使用 collection_select 并从 sqlite3 收到意外错误 - 有人知道为什么吗?

ruby-on-rails - 比较 Time.now 与模型日期

mysql - 如何锁定队列中的行?

Php mysql 事务未插入所有查询

Java EE 7 - 如何从容器内部启动事务?

ruby-on-rails-3 - RoR "file_field"和 Twitter Bootstrap

ruby-on-rails-3 - 路由在 RoR 中不起作用

ruby-on-rails - 无法使用 Devise(Rails 4、devise 3、formtastic、geocoder)在我的 Rails 4 应用程序中编辑用户(帐户更新)的自定义字段

c# - 有没有办法只在 dapper 中读取未提交的行?

javascript - 如何在 Loopback 中实现 ACID 事务