转自:http://ihower.tw/rails3/activerecord-others.html#transactions
交易Transactions
Transaction (交易)保证所有资料的操作都只有在成功的情况下才会写入到资料库,最著名的例子也就是银行的帐户交易,只有在帐户
提领金额及存入帐户这两个动作都成功的情况下才会将这笔操作写入资料库,否则在其中一个动作因为某些原因失败的话就会放弃
所有已做的操作将资料回复到交易前的状态。在Rails中使用交易的方式像这样:
ActiveRecord::Base.transaction dodavid.withdrawal(100)mary.deposit(100)
end
你可以在一个交易中包含不同Active Record的类别或物件,这是因为交易是以资料库连线为范围,而不是个别Model:
User.transaction doUser.create!(:name => 'ihower')Feed.create!
end
注意到这里我们要使用create!
而不是create
,这是因为前者验证失败才会丢出例外,好让整个交易失败。同理,在交易里做更新应该使用update_attributes!
而不是update_attributes
。
单一Model的save
及destroy
方法已经帮你使用transaction包起来了,当资料验证失败或其中的回呼发生例外时,Rails就会触发rollback。所以下述的交易区块是多余的不需要写:
User.transaction do # 这是多余的User.create!(:name => 'ihower')
end
另外,由于资料的更新要在交易完成后才能被读取到,所以如果你在after_save
回呼里让外部服务存取(例如呼叫全文搜寻引擎做索引),很可能因为交易尚未完成,会读取不到更新。这时候必须改用after_commit
这个回呼,才能确保读取到交易完成后的资料。