From 2ec17da8985afb78ae619c72d7eaebccc38afbef Mon Sep 17 00:00:00 2001 From: Nick Mills-Barrett Date: Sun, 5 Nov 2023 11:11:56 +0000 Subject: [PATCH] Rewrite highest priority rule txn to use FOR UPDATE in one query --- synapse/storage/databases/main/push_rule.py | 17 ++++++----------- 1 file changed, 6 insertions(+), 11 deletions(-) diff --git a/synapse/storage/databases/main/push_rule.py b/synapse/storage/databases/main/push_rule.py index 17ea6907f1cd..0aa229a44be8 100644 --- a/synapse/storage/databases/main/push_rule.py +++ b/synapse/storage/databases/main/push_rule.py @@ -465,23 +465,18 @@ def _add_push_rule_highest_priority_txn( conditions_json: str, actions_json: str, ) -> None: + sql = """ + SELECT COUNT(*), MAX(priority) FROM push_rules" + WHERE user_name = ? and priority_class = ? + """ + if isinstance(self.database_engine, PostgresEngine): - # Postgres doesn't do FOR SHARE on aggregate functions, so select the rows first - # then re-select the count/max below. - sql = """ - SELECT * FROM push_rules - WHERE user_name = ? and priority_class = ? - FOR SHARE - """ + sql += " FOR UPDATE" else: # Annoyingly SQLite doesn't support row level locking, so lock the whole table self.database_engine.lock_table(txn, "push_rules") # find the highest priority rule in that class - sql = ( - "SELECT COUNT(*), MAX(priority) FROM push_rules" - " WHERE user_name = ? and priority_class = ?" - ) txn.execute(sql, (user_id, priority_class)) res = txn.fetchall() (how_many, highest_prio) = res[0]