0

過去我並沒有很多死鎖問題的經驗,但我越來越多地嘗試使用ActiveJob並同時處理這些作業,所以我遇到了這個問題。下面顯示了創建它的一個Job的示例。它的運作方式是我開始ImportGameParticipationsJob,它排隊了一堆CreateOrUpdateGameParticipationJobs在Rails中使用ActiveJob時,如何避免數據庫發生死鎖?

當試圖阻止我的SQL Server提醒我發生大量死鎖錯誤時,原因可能在哪裏發生?從簡單的選擇記錄到填充對象,我能否陷入僵局?或者只有當我試圖保存/更新下面的process_records方法中的記錄時才能保存?

ImportGameParticipationsJob

class ImportGameParticipationsJob < ActiveJob::Base 
    queue_as :default 

    def perform(*args) 
    import_participations(args.first.presence) 
    end 

    def import_participations(*args) 
    games = Game.where(season: 2016) 
    games.each do |extract_record| 
     CreateOrUpdateGameParticipationJob.perform_later(extract_record.game_key) 
    end 
    end 
end 

CreateOrUpdateGameParticipationJob

class CreateOrUpdateGameParticipationJob < ActiveJob::Base 
    queue_as :import_queue 

    def perform(*args) 
    if args.first.present? 
     game_key = args.first 

     # get all particpations for a given game 
     game_participations = GameRoster.where(game_key: game_key) 
     process_records(game_participations) 
    end 
    end 

    def process_records(participations) 
    # Loop through participations and build record for saving... 
    participations.each do |participation| 
     if participation.try(:player_id) 
     record = create_or_find(participation) 
     record = update_record(record, participation) 
     end 

     begin 
     if record.valid? 
      record.save 
     else 

     end 
     rescue Exception => e 

     end 
    end 
    end 

    def create_or_find(participation) 
    participation_record = GameParticipation.where(
     game_id: participation.game.try(:id), 
     player_id: participation.player.try(:id)) 
     .first_or_initialize do |record| 
     record.game = Game.find_by(game_key: participation.game_key) 
     record.player = Player.find_by(id: participation.player_id) 
     record.club  = Club.find_by(club_id: participation.club_id) 
     record.status = parse_status(participation.player_status) 
    end 
    return participation_record 
    end 

    def update_record(record, record) 
    old_status = record.status 
    new_status = parse_status(record.player_status) 
    if old_status != new_status 
     record.new_status = record.player_status 
     record.comment = "status was updated via participations import job" 
    end 
    return record 
    end 

end 

回答

0

他們最近更新和補充,你可以設置應與死鎖幫助的其他選項。我有同樣的問題,並在4.1上,移動到4.1.1爲我解決這個問題。

https://github.com/collectiveidea/delayed_job_active_record

https://rubygems.org/gems/delayed_job_active_record

問題鎖定工作

您可以嘗試使用傳統的鎖碼。它通常比較慢,但對某些人來說效果更好。

延遲::後端:: ActiveRecord.configuration.reserve_sql_strategy =:default_sql

+0

我沒有使用'DelayedJob',使用'Sidekiq' – daveomcd

+0

啊,我們正在轉換現在就Sidekiq上一堆應用程序,所以我希望我不會遇到同樣的事情。 –