aasm和ActiveRecord事務

這裏的aasm版本是3.4.0html

aasm在版本3.0.13後就支持ActiveRecord事務了,這在文檔中已經說清楚了,可是還有些使用上的細節沒有說清楚。數據庫

  1. aasm中使用ActiveRecord事務,所謂的事務是指在一個transition中發生的數據庫變化會在出現異常後進行回滾,並且必須是調用帶!的aasm方法纔會包裹事務,舉例說:
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
  1. 怎麼使用本身的事務,若是本身的業務邏輯涉及的東西比較多,除了狀態機的部分,可能還有其餘的數據庫操做,那麼就要本身寫事務代碼,好比:
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

相關文章
相關標籤/搜索