Skip to content

Commit

Permalink
Check if SAVE_LIMIT is bigger than 0 before running any queries.
Browse files Browse the repository at this point in the history
On MS SQL Server, the select_for_update() query below will take a
ROWLOCK,UPDLOCK on every row in the Task table. This happens because it locks
every row it needs to look at to return the result of the query.
Since there is no index on the default sorting column "stopped", it has
to do a full table scan, and hence it will take rowlocks on each row
in the table.
On other databases, it will still do a full table scan, but without the
excessive locking.
If SAVE_LIMIT is 0 the result of this query is unused, so by moving the
check a level higher we avoid running this expensive query.
  • Loading branch information
rubendv committed Dec 16, 2021
1 parent 85baacc commit 32e7a35
Showing 1 changed file with 5 additions and 4 deletions.
9 changes: 5 additions & 4 deletions django_q/cluster.py
Original file line number Diff line number Diff line change
Expand Up @@ -474,10 +474,11 @@ def save_task(task, broker: Broker):
# SAVE LIMIT > 0: Prune database, SAVE_LIMIT 0: No pruning
close_old_django_connections()
try:
with db.transaction.atomic():
last = Success.objects.select_for_update().last()
if task["success"] and 0 < Conf.SAVE_LIMIT <= Success.objects.count():
last.delete()
if Conf.SAVE_LIMIT > 0:
with db.transaction.atomic():
last = Success.objects.select_for_update().last()
if task["success"] and Conf.SAVE_LIMIT <= Success.objects.count():
last.delete()
# check if this task has previous results
if Task.objects.filter(id=task["id"], name=task["name"]).exists():
existing_task = Task.objects.get(id=task["id"], name=task["name"])
Expand Down

0 comments on commit 32e7a35

Please sign in to comment.