Techioz Blog

Sidekiq ジョブがモデルの after_commit コードから失敗するのはなぜですか?

概要

この Sidekiq ジョブを実行すると、Foo レコードが正常に作成されます。しかし、Foo の after_commit でエラーが発生するため、ジョブ全体が失敗し、デッド ジョブ キューに入れられてしまいます。 after_commit エラーを修正してジョブを再実行すると、別の Foo レコードが作成されます (または再試行時に作成されます 😬) これは望ましくありません。

Foo レコードが正常に作成された後、PerformAndCreateFooJob が正常に完了することを期待します。 after_commit ロジックによってジョブが失敗することはありません。

class PerformAndCreateFooJob
  include Sidekiq::Job
  sidekiq_options retry: 0

  def perform = Foo.create
end
class Foo < ApplicationRecord
  after_commit -> () { raise }
end

解決策

それは、あなたが呼び出している作成の一部(実際には保存の一部)であるためです。

ガイドで説明されているように、insert を使用してコールバックをスキップする

追加する価値があります…ジョブが冪等であることを確認することがベスト プラクティスです。ジョブが再試行される理由は数多くあります。これには、独自のアプリ ロジックだけでなく、他のシステム条件も含まれます。通常の状況では、これは最初に find_by を使用するだけで済みます (ジョブ キュー ロジックが同じレコード/データに対して多数のジョブを作成する可能性が低いと仮定します)。または、DB 内で一意の制約を設定し、そこで障害を救済するロジックが必要になる場合もあります。 。