aasm和ActiveRecord事务

这里的aasm版本是3.4.0

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

如果你调用了:

job.run!

那么状态、doing_something_to_database就都被包裹在了事务中,当里面出现任何异常,所有的数据库操作都会回滚。可以这样做测试:

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方法,将状态变化保存到数据中

Job.transaction do
    job.do_abc
    job.run
    job.save
    job.do_xyz
    ...
end

另外 before是每次都会执行,不管这个记录状态有没有变化 就算状态改变过了,再调用事,before依然会执行

转载于:https://my.oschina.net/u/855913/blog/1547340

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值