1. 使用事物的緣由數據庫
保證數據一致性, 當其中出現一個失敗的時候,操做能夠回滾app
好比:框架
ActiveRecord::Base.transaction do david.withdrawal(100) # withdrawal失敗必須觸發 exception mary.deposit(100) # deposit失敗必須觸發 exception end
return false 不會出發操做回滾, 因此事物中要使用!的方法, 好比 save! update!ide
before_save 等callback也包含在事物中, 若是但願觸發事物回滾, 須要能拋出異常測試
若是不希回滾則不拋出異常 或者放在事物以外 用after_commit等callbacl來處理spa
不要在事務內部去捕捉 ActiveRecord::RecordInvalid 異常。由於某些數據庫下,這個異常會致使事務失效,好比 Postgres。一旦事務失效,要想讓代碼正確工做,就必須從頭從新執行事務。翻譯
另外,測試回滾或者事務回滾相關的回調時,最好關掉 transactional_fixtures 選項,通常的測試框架中,這個選項是打開的。rest
Also have in mind that exceptions thrown within a transaction block will be propagated (after triggering the ROLLBACK), so you should be ready to catch those in your application code.code
One exception is the ActiveRecord::Rollback
exception, which will trigger a ROLLBACK when raised, but not be re-raised by the transaction block.blog
Warning: one should not catch ActiveRecord::StatementInvalid
exceptions inside a transaction block. ActiveRecord::StatementInvalid
exceptions indicate that an error occurred at the database level, for example when a unique constraint is violated. On some database systems, such as PostgreSQL, database errors inside a transaction cause the entire transaction to become unusable until it's restarted from the beginning. Here is an example which demonstrates the problem:
# Suppose that we have a Number model with a unique column called 'i'. Number.transaction do Number.create(i: 0) begin # This will raise a unique constraint error... Number.create(i: 0) rescue ActiveRecord::StatementInvalid # ...which we ignore. end # On PostgreSQL, the transaction is now unusable. The following # statement will cause a PostgreSQL error, even though the unique # constraint is no longer violated: Number.create(i: 1) # => "PGError: ERROR: current transaction is aborted, commands # ignored until end of transaction block" end