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 内で一意の制約を設定し、そこで障害を救済するロジックが必要になる場合もあります。 。