我正在尝试构建一个表,该表将充当第三方服务的批量同步队列。
下面的方法应该不言自明;但需要明确的是,它的目的是向 delayed_syncs
表中添加一个具有 status: :queued
的新可更新对象(多态关系)。
多态关系+status
(updatable_id
, updatable_type
, status
) 存在唯一性约束应该会导致已在队列中且具有 :queued status
的可更新对象在此处失败并落入救援 block 。
我看到的问题是,每当 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
您仍然可以安全地使用 rescue
来处理日志记录清理。
可以找到关于此的更多详细信息的文档 here .
关于sql - 拯救 ActiveRecord::RecordNotUnique 时的问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36296721/