diff --git a/synapse/storage/_base.py b/synapse/storage/_base.py index 4ac61be895..c15cec0c78 100644 --- a/synapse/storage/_base.py +++ b/synapse/storage/_base.py @@ -160,9 +160,19 @@ class LoggingTransaction(object): start = time.time() * 1000 try: - return self.txn.execute( - sql, *args, **kwargs - ) + i = 0 + N = 5 + while True: + try: + return self.txn.execute( + sql, *args, **kwargs + ) + except self.database_engine.module.DatabaseError as e: + if self.database_engine.is_deadlock(e) and i < N: + i += 1 + logger.warn("[SQL DEADLOCK] {%s}", self.name) + continue + raise except Exception as e: logger.debug("[SQL FAIL] {%s} %s", self.name, e) raise diff --git a/synapse/storage/engines/maria.py b/synapse/storage/engines/maria.py index 7fcb706a60..a279bfaf44 100644 --- a/synapse/storage/engines/maria.py +++ b/synapse/storage/engines/maria.py @@ -40,3 +40,8 @@ class MariaEngine(object): ) db_conn.commit() prepare_database(db_conn, self) + + def is_deadlock(self, error): + if isinstance(error, self.module.InternalError): + return error.sqlstate == 40001 and error.errno == 1213 + return False diff --git a/synapse/storage/engines/sqlite3.py b/synapse/storage/engines/sqlite3.py index e802b5d5fd..72c11df461 100644 --- a/synapse/storage/engines/sqlite3.py +++ b/synapse/storage/engines/sqlite3.py @@ -32,3 +32,6 @@ class Sqlite3Engine(object): def prepare_database(self, db_conn): prepare_sqlite3_database(db_conn) prepare_database(db_conn, self) + + def is_deadlock(self, error): + return False