summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorYorhel <git@yorhel.nl>2022-08-09 10:49:29 +0200
committerYorhel <git@yorhel.nl>2022-08-09 10:52:15 +0200
commit3195c481157e45bc9cc37c28be22ebf1b663c208 (patch)
tree1e334aec2b896862de78aeabe3f98188d38875ff /lib
parentefbed0eb912801f5cc618ea384362f11518cde65 (diff)
Avoid a deadlock when image vote & DB edit happen at the same time
Happened about once day. Problem is that both a DB edit and a related image vote want to update the same rows in the users and images tables, but do so in different order. This workaround seems to do the trick.
Diffstat (limited to 'lib')
-rw-r--r--lib/VNWeb/Images/Vote.pm3
1 files changed, 3 insertions, 0 deletions
diff --git a/lib/VNWeb/Images/Vote.pm b/lib/VNWeb/Images/Vote.pm
index 5999fb3c..8831c0af 100644
--- a/lib/VNWeb/Images/Vote.pm
+++ b/lib/VNWeb/Images/Vote.pm
@@ -71,6 +71,9 @@ elm_api ImageVote => undef, {
return elm_Unauth if !can_vote;
return elm_CSRF if !validate_token $data->{votes};
+ # Lock the users table early to prevent deadlock with a concurrent DB edit that attempts to update c_changes.
+ tuwf->dbExeci('SELECT c_imgvotes FROM users WHERE id =', \auth->uid, 'FOR UPDATE');
+
# Find out if any of these images are being overruled
enrich_merge id => sub { sql 'SELECT id, bool_or(ignore) AS overruled FROM image_votes WHERE id IN', $_, 'GROUP BY id' }, $data->{votes};
enrich_merge id => sql('SELECT id, NOT ignore AS my_overrule FROM image_votes WHERE uid =', \auth->uid, 'AND id IN'),