過去我並沒有很多死鎖問題的經驗,但我越來越多地嘗試使用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
我沒有使用'DelayedJob',使用'Sidekiq' – daveomcd
啊,我們正在轉換現在就Sidekiq上一堆應用程序,所以我希望我不會遇到同樣的事情。 –