Skip to content

Commit 04a1d93

Browse files
committed
Fix persisting tasks for PostgreSQL on concurrent INSERTs
PostgreSQL fails and aborts the current transaction when it hits a duplicate key conflict during two concurrent INSERTs for the same value of an unique index. We need to explicitly indicate unique_by to ignore duplicate rows by this value when inserting
1 parent 6236739 commit 04a1d93

File tree

2 files changed

+12
-1
lines changed

2 files changed

+12
-1
lines changed

app/models/solid_queue/recurring_task.rb

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,17 @@ def wrap(args)
1919
def from_configuration(key, **options)
2020
new(key: key, class_name: options[:class], schedule: options[:schedule], arguments: options[:args])
2121
end
22+
23+
def create_or_update_all(tasks)
24+
if connection.supports_insert_conflict_target?
25+
# PostgreSQL fails and aborts the current transaction when it hits a duplicate key conflict
26+
# during two concurrent INSERTs for the same value of an unique index. We need to explicitly
27+
# indicate unique_by to ignore duplicate rows by this value when inserting
28+
upsert_all tasks.map(&:attributes_for_upsert), unique_by: :key
29+
else
30+
upsert_all tasks.map(&:attributes_for_upsert)
31+
end
32+
end
2233
end
2334

2435
def delay_from_now

lib/solid_queue/dispatcher/recurring_schedule.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ def task_keys
4343

4444
private
4545
def persist_tasks
46-
SolidQueue::RecurringTask.upsert_all configured_tasks.map(&:attributes_for_upsert), record_timestamps: true
46+
SolidQueue::RecurringTask.create_or_update_all configured_tasks
4747
end
4848

4949
def reload_tasks

0 commit comments

Comments
 (0)