这里的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