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上一堆应用程序,所以我希望我不会遇到同样的事情。 –