У меня не было много опыта с проблемами блокировки в прошлом, но чем больше я пытаюсь работать с ActiveJob и одновременно обрабатывать эти задания, я сталкиваюсь с этой проблемой. Пример одного задания, создающего его, показан ниже. То, как он работает, я начинаю ImportGameParticipationsJob
, и он ставит в очередь кучу CreateOrUpdateGameParticipationJobs
.Как я могу избежать взаимоблокировок в моей базе данных при использовании ActiveJob в Rails?
При попытке помешать моему 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
Я не использую 'DelayedJob', используя' Sidekiq' – daveomcd
Ааа, мы преобразования в Sidekiq сейчас на кучу поэтому я надеюсь, что тогда я не столкнусь с этим. –