Rails 无法救援 PG::UniqueViolation - 为什么?

问题描述 投票:0回答:1

尝试从 Rails (7.0.8) 开发环境中的 Sidekiq (7.2.1) 作业中的块中挽救

PG::UniqueViolation
错误,在 Ubuntu 20.04 上使用本地 PostgreSQL 14.10 db 在 Ruby 3.2.2 修订版 e51014f9c0 上运行时失败。我在测试时使用
InitThingsJob.new.perform_now
从控制台启动该作业,并在第一个位置有一个已知的重复项。

尝试

rescue ActiveRecord::RecordNotUnique
rescue PG::UniqueViolation, ActiveRecord::RecordNotUnique
同样会失败。

失败的函数对从包含对象集合的外部 API 接收到的响应进行操作。有时,但很少见的是,外部 API 具有重复的条目。我们不能拥有这些,因此数据库在可靠的 id 字段上有一个唯一索引。

它的目的是从响应中的集合创建一个数组,然后在块中迭代该数组并创建每个元素的记录。如果从一个元素成功创建了一个元素,那么它会移动数组以删除该元素。如果出现

PG::UniqueViolation
错误,则会挽救该错误,移动数组以删除导致错误的元素,并使用截断的数组重试该块。

  def create_x_from_y_query
    response_objs = @response.body["data"]["objects"]

    begin
      response_objs.each do |obj|
        @obj = Obj.new(k_id: obj["k_id"], etc: obj["etc"])
        @obj.save
        #... other things...
        response_objs.shift
      end
    rescue PG::UniqueViolation
      logger.warn "Warning stuff."
      response_objs.shift
      retry
    end

  end

预期的行为是挽救

PG::UniqueViolation
错误,移动产生错误的可枚举元素,然后使用截断的数组重试该块。

当遇到重复项时,作业会因错误

PG::UniqueViolation
退出,返回:

E, [2024-01-23T13:57:36.755697 #1213779] ERROR -- : Error performing InitThingsJob (Job ID: 1312b3a9-8359-4cb6-a16d-8442370d815b) from Sidekiq(default) in 1548.0ms: ActiveRecord::RecordNotUnique (PG::UniqueViolation: ERROR:  duplicate key value violates unique constraint "index_obj_on_k_id"
DETAIL:  Key (k_id)=(<value>) already exists.
):
/home/xxx/.rbenv/versions/3.2.2/lib/ruby/gems/3.2.0/gems/activerecord-7.0.8/lib/active_record/connection_adapters/postgresql_adapter.rb:768:in `exec_params'

... Down the trace until we arrive at:

/home/xxx/.rbenv/versions/3.2.2/lib/ruby/gems/3.2.0/gems/activerecord-7.0.8/lib/active_record/connection_adapters/postgresql_adapter.rb:768:in `exec_params': PG::UniqueViolation: ERROR:  duplicate key value violates unique constraint "index_obj_on_k_id" (ActiveRecord::RecordNotUnique)
DETAIL:  Key (k_id)=(<value>) already exists.
/home/xxx/.rbenv/versions/3.2.2/lib/ruby/gems/3.2.0/gems/activerecord-7.0.8/lib/active_record/connection_adapters/postgresql_adapter.rb:768:in `exec_params': ERROR:  duplicate key value violates unique constraint "index_objs_on_k_id" (PG::UniqueViolation)
DETAIL:  Key (k_id)=(<value>) already exists.

处理事务内唯一约束异常的一些回复表明,他们的问题是由并发引起的,并在事务块之外处理救援来解决它或救援ActiveRecord错误而不是PG错误,但在这里似乎都不起作用,并且错误输出不一样。

ruby-on-rails postgresql sidekiq
1个回答
0
投票

save方法不会引发异常来救援

您需要使用 save! 方法,以便引发异常。

从你的日志中,也许你需要拯救

ActiveRecord::RecordNotUnique
异常。

© www.soinside.com 2019 - 2024. All rights reserved.