這裏的aasm版本是3.4.0html
aasm在版本3.0.13後就支持ActiveRecord事務了,這在文檔中已經說清楚了,可是還有些使用上的細節沒有說清楚。數據庫
class Job < ActiveRecord::Base include AASM aasm do state :sleeping, :initial => true state :running event :run do transitions :from => :sleeping, :to => :running after :doing_something_to_database end end def doing_something_to_database ... end end
若是你調用了:api
job.run!
那麼狀態、doing_something_to_database就都被包裹在了事務中,當裏面出現任何異常,全部的數據庫操做都會回滾。能夠這樣作測試:ruby
class Job < ActiveRecord::Base include AASM aasm do state :sleeping, :initial => true state :running event :run do transitions :from => :sleeping, :to => :running after :doing_something_to_database before :throw_error end end def doing_something_to_database ... end def throw_error raise 'error!!!' end end
Job.transaction do job.do_abc job.run! job.do_xyz ... end
這個時候就會讓人迷惑了,由於這是一個嵌套事務(能夠查看這個連接,嵌套事務),咱們本身的事務中包了一個aasm提供的事務。這個時候有兩種辦法來處理: 第一種,官方提供的方法:測試
class Job < ActiveRecord::Base include AASM aasm :requires_new_transaction => false do ... end ... end
第二種,不用!方法,可是得本身加save方法,將狀態變化保存到數據中ui
Job.transaction do job.do_abc job.run job.save job.do_xyz ... end
另外 before是每次都會執行,無論這個記錄狀態有沒有變化 就算狀態改變過了,再調用事,before依然會執行code