after_commit或after_create表示使用事务的模型?

时间:2014-09-25 18:22:54

标签: ruby-on-rails ruby email

我需要创建用户并在注册时发送电子邮件:

class User < ActiveRecord::Base

  after_commit :send_email, on: :create # I believe it's better than after_create
  # after_create :send_email, on: :create

  class << self
    def create_with_some_params(params)
      #....
      user.transaction do
        if user.save && some_condition
          user.category = category
          raise ActiveRecord::Rollback unless user.category.persisted?
        end  
      end

      rescue => e
        logger.error e.message
      ensure 
        [user, some_data]
      end
    end
   end

  send_email(....)
       #.....
  end
end

起初我使用after_create发送电子邮件,在交易中发送电子邮件。而且通常会发生超时。所以我开始使用after_commit,因为在事务之后它被称为,因此电子邮件缓慢不会发生超时。

因此,对于user.transaction do的情况,我应该使用after_commit代替after_create来避免交易超时吗?

1 个答案:

答案 0 :(得分:1)

我更喜欢这些场景中的after_commit,因为它确保整个事务完成并在“行为”之前提交给数据库。

但是,有一件事可以帮助解决电子邮件的缓慢问题,即添加SidekiqDelayedJob(后台处理)等内容来提高应用性能,尤其是Rails出了名的慢速邮件。

我们已经在工作中使用Sidekiq几年了,因为我们的应用程序是一个内容交付系统,所以这是天赐之物!

MyMailer.delay.send_some_email(stuff) # this is how we can asynchronously send an email with Sidekiq

使用后台处理器可以消除事务超时,如果您(a)想要坚持使用after_create或(b)只想加速邮件:)!