繁体   English   中英

ActiveRecord交易前回调

[英]ActiveRecord before-transaction callback

问题 :我正在寻找一个ActiveRecord(Rails 3.2)回调钩子,该钩子将在数据库事务开始之前执行。

如果它不存在(并且我不认为它存在),那么我正在寻找猴子补丁ActiveRecord中的任何建议,以便我们自己实现这种方法。

我尝试过的

看了ActiveRecord文档并试用了代码之后,似乎只有'after_commit'可以保证在事务外部执行。 其他所有内容(“ before_validation”,“ before_save”,“ before_commit”)都在事务内运行。 我尝试覆盖“交易”方法:

class User < ActiveRecord::Base
  included do |base|
    base.instance_eval do
    def before_transaction
      ### DO STUFF
    end

    def transaction(options = {}, &block)
       before_transaction { super(options, &block) }
    end
  end
end

但这很复杂,因为事务是一个类方法,并且必须为模型的每个实例注册回调。 最重要的是,不能保证它可以在数据库事务之外运行,因为它可能是嵌套的:

ActiveRecord::Base.transaction do
  ActiveRecord::Base.transaction do
    user.update_attribute(name: "Hodor")
  end
end

由于ActiveRecord的实现方式,我不确定我想要什么,因为可能无法知道另一个事务是否已经开始并随后调用回调。 无论如何,我认为这里值得一问。

背景

我正在尝试将现有的Rails模型(称为用户)“同步”到其他地方的用户服务。 用户服务应充当真理的来源。

每当Rails用户模型发生更新时,我想先验证并提交对用户服务的更改,然后再保存到数据库(仅Rails项目使用)。 然后,Rails项目的DB充当直写式高速缓存(为什么要使用数据库作为高速缓存?传统代码原因)。

如果我们可以在写入数据库之前调用该服务,则不必担心回滚事务(以及处理回滚失败时发生的情况!)。 但是,我很犹豫在打开的数据库事务中间调用服务,这就是为什么我要研究是否有可能构建“ before_transaction”回调的原因。

为什么不编写处理所有此功能的服务对象?

class UserService
  attr_accessor :user

  def initialize(user, params)
    @user = user
    @params = params
  end

  def save
    external_result = API.call_to_external

    if external_result
      @user.update(@params)
    end
  end
end

user_service = UserService.new(user, params)
user_service.save

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM