sql – 抢救ActiveRecord :: RecordNotUnique时的问题

我正在尝试构建一个表,它将作为第三方服务的批量同步队列.

以下方法应该说明一切;但要明确的是,它的目的是添加一个新的可更新对象(多态关系),其状态为::排队到delayed_syncs表.

对多态关系状态(updatable_id,updatable_type,status)存在唯一性约束,这会导致队列中已有的可更新对象:queued status在此处失败并进入rescue块.

我看到的问题是,只要触发了find_by生成的SELECT,整个方法就会失败:

ActiveRecord::StatementInvalid

错误.

我发现的信息表明在INSERT失败后会出现ROLLBACK或RELEASE SAVEPOINT,但我不确定如何在此处完成.

上述方法:

def self.enqueue(updatable:, action:)
  DelayedSync.create(updatable: updatable, status: :queued, action: action)
rescue ActiveRecord::RecordNotUnique
  queued_update = DelayedSync.find_by(updatable: updatable, status: :queued, action: :sync_update)
  if action == :sync_delete && queued_update.present?
    queued_update.sync_delete!
  else
    Rails.logger.debug "#{updatable.class.name} #{updatable.id} already queued for sync, skipping."
  end
end

最佳答案 您可以使用ActiveRecord事务来确保全部或全无更新,而不是依赖于逻辑的异常处理.

像这样:

ActiveRecord::Base.transaction do
  DelayedSync.create!(updatable: updatable, status: :queued, action: action)
end

您仍然可以安全地利用救援来处理日志记录清理.

有关详细信息的文档可以在here找到.

点赞