From b22ba61c80c49e76ec1df270abf6c1927cd91891 Mon Sep 17 00:00:00 2001 From: Toufik Ben Jaa Date: Tue, 7 Jan 2020 16:41:14 +0000 Subject: [PATCH] [FIX] website: rollback transaction before creating new one - When rendering a website page, exceptions might happens. If so, an error page is displayed, to do so we create a new psyscopg cursor to read the view in database and render it. But if the current (failed) transaction was holding a lock, the new cursor might have to wait for this lock to be released further down the line. However, this will only happen after the request is done (and in fact it won't happen). As a result, the current thread/worker is frozen until its timeout is reached. So rolling back the transaction will release any potential lock and, since we are in a case where an exception was raised, the transaction shouldn't be committed in the first place. closes odoo/odoo#44085 X-original-commit: 7a61c89da5ccaed983275eb5f4986475ebf8b48d Signed-off-by: Toufik Benjaa (tbe) --- addons/http_routing/models/ir_http.py | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/addons/http_routing/models/ir_http.py b/addons/http_routing/models/ir_http.py index 35ecc63ad96..de512bdcdd8 100644 --- a/addons/http_routing/models/ir_http.py +++ b/addons/http_routing/models/ir_http.py @@ -627,6 +627,21 @@ class IrHttp(models.AbstractModel): if not request.uid: cls._auth_method_public() + + # We rollback the current transaction before initializing a new + # cursor to avoid potential deadlocks. + + # If the current (failed) transaction was holding a lock, the new + # cursor might have to wait for this lock to be released further + # down the line. However, this will only happen after the + # request is done (and in fact it won't happen). As a result, the + # current thread/worker is frozen until its timeout is reached. + + # So rolling back the transaction will release any potential lock + # and, since we are in a case where an exception was raised, the + # transaction shouldn't be committed in the first place. + request.env.cr.rollback() + with registry(request.env.cr.dbname).cursor() as cr: env = api.Environment(cr, request.uid, request.env.context) if code == 500: