From 1d0940d96f3f5de45b38a9ddad9af65087dd04f3 Mon Sep 17 00:00:00 2001 From: Nicolas Lempereur Date: Tue, 4 Sep 2018 18:15:12 +0200 Subject: [PATCH] [FIX] base: allow get_template serialization retry When two transactions conflicts (eg. deleting same data, see [1]) Odoo will retry the whole transaction several times hoping for the best. But when rendering template, the error handling would prevent this feature. For example a recurring issue was: - loading quickly two times the /web route - for each recompute the assets => this could lead to 2 concurrents transactions that would delete previous same attachment (ie. DELETE FROM ir_attachment where id=3). With this changeset, when getting a template fails because of a transaction rollback, we let the issue bubble up so our retry system is used. So instead of a "500 Internal Server Error" page and in log: bad query: b'DELETE FROM ir_attachment WHERE id IN (3)' ERROR: could not serialize access due to concurrent update "GET /web HTTP/1.1" 200 - "GET /web HTTP/1.1" 500 - ... big traceback ... load could not load template we would get the requested page without error and: bad query: b'DELETE FROM ir_attachment WHERE id IN (3)' ERROR: could not serialize access due to concurrent update "GET /web HTTP/1.1" 200 - SERIALIZATION_FAILURE, retry 1/5 in 0.8920 sec.. "GET /web HTTP/1.1" 200 - As a side node, the issue was exacerbated in some instances: - when running a database on another server: assets are recomputed - when a module was installed/uninstalled: assets may are recomputed - when updating the source code: assets may be recomputed - when starting server: requests could be stacked waiting for readiness - when using google chrome: the "Use a prediction service to load pages more quickly" option may load a page two times. for example: -> an URL is entered in address bar -> a prediction request to it is started URL -> go to this page (Enter) when that request is not already resolved -> the prediction request is cancelled and a new request is started [1] https://www.postgresql.org/docs/9.6/static/transaction-iso.html#XACT-REPEATABLE-READ note: 10.0 backport of 11.0 #26778 opw-1849167 closes #26785 --- odoo/addons/base/ir/ir_qweb/qweb.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/odoo/addons/base/ir/ir_qweb/qweb.py b/odoo/addons/base/ir/ir_qweb/qweb.py index 82a3cb0fadd..759fdea4054 100644 --- a/odoo/addons/base/ir/ir_qweb/qweb.py +++ b/odoo/addons/base/ir/ir_qweb/qweb.py @@ -5,6 +5,7 @@ from lxml import etree, html import re import traceback from itertools import count +from psycopg2.extensions import TransactionRollbackError from textwrap import dedent import werkzeug from werkzeug.utils import escape as _escape @@ -313,7 +314,7 @@ class QWeb(object): values = dict(self.default_values(), **values) try: return compiled(self, append, values, options, log) - except QWebException, e: + except (QWebException, TransactionRollbackError) as e: raise e except Exception, e: path = log['last_path_node']