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