Skip to content

[16.0][IMP] queue_job: retry concurrency errors wrapped in other exceptions - #1013

Open
RicardCForgeFlow wants to merge 1 commit into
OCA:16.0from
ForgeFlow:16.0-imp-queue_job-retry-wrapped-concurrency-errors
Open

RicardCForgeFlow wants to merge 1 commit into
OCA:16.0from
ForgeFlow:16.0-imp-queue_job-retry-wrapped-concurrency-errors

Conversation

@RicardCForgeFlow

@RicardCForgeFlow RicardCForgeFlow commented Oct 20, 2026 •

Copy link
Copy Markdown

A job that fails with a serialization failure, deadlock or lock timeout is retried only if the error reaches the runner as an OperationalError. When some code wraps it in another exception (Odoo does it in auth_signup, for example), the job fails and is never retried.
The runner now looks for the concurrency error in the exception chain before deciding. Errors raised by the job itself and any other error behave as before.

Example of job failed with this kind of error and not retried:

image
Exception Information
Exception:odoo.addons.auth_signup.models.res_partner.SignupError
Traceback (most recent call last):
  File "/home/ricard/odoo/odoo16/odoo/addons/auth_signup/models/res_users.py", line 145, in _create_user_from_template
    with self.env.cr.savepoint():
  File "/home/ricard/odoo/odoo16/odoo/odoo/sql_db.py", line 82, in __exit__
    self.close(rollback=exc_type is not None)
  File "/home/ricard/odoo/odoo16/odoo/odoo/sql_db.py", line 86, in close
    self._close(rollback)
  File "/home/ricard/odoo/odoo16/odoo/odoo/sql_db.py", line 110, in _close
    self._cr.flush()
  File "/home/ricard/odoo/odoo16/odoo/odoo/sql_db.py", line 134, in flush
    self.transaction.flush()
  File "/home/ricard/odoo/odoo16/odoo/odoo/api.py", line 899, in flush
    env_to_flush.flush_all()
  File "/home/ricard/odoo/odoo16/odoo/odoo/api.py", line 763, in flush_all
    self[model_name].flush_model()
  File "/home/ricard/odoo/odoo16/odoo/odoo/models.py", line 5676, in flush_model
    self._flush(fnames)
  File "/home/ricard/odoo/odoo16/odoo/odoo/models.py", line 5778, in _flush
    model.browse(ids)._write(vals)
  File "/home/ricard/odoo/odoo16/odoo/odoo/models.py", line 3917, in _write
    cr.execute(query, params + [sub_ids])
  File "/home/ricard/odoo/odoo16/odoo/odoo/sql_db.py", line 324, in execute
    res = self._obj.execute(query, params)
          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
psycopg2.errors.SerializationFailure: could not serialize access due to concurrent update


During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/home/ricard/odoo/worktrees/queue-job-pristine/queue_job/controllers/main.py", line 155, in _runjob
    cls._try_perform_job(env, job)
  File "/home/ricard/odoo/worktrees/queue-job-pristine/queue_job/controllers/main.py", line 102, in _try_perform_job
    job.perform()
  File "/home/ricard/odoo/worktrees/queue-job-pristine/queue_job/job.py", line 533, in perform
    self.result = self.func(*tuple(self.args), **self.kwargs)
                  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/ricard/odoo/worktrees/queue-job-demo/queue_job_demo/models/queue_job_demo.py", line 23, in create_portal_user
    return self.env["res.users"].sudo()._create_user_from_template(
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/ricard/odoo/odoo16/odoo/addons/auth_signup/models/res_users.py", line 149, in _create_user_from_template
    raise SignupError(ustr(e))
odoo.addons.auth_signup.models.res_partner.SignupError: could not serialize access due to concurrent update

@OCA-git-bot

Copy link
Copy Markdown
Contributor

Hi @sbidoul, @guewen,
some modules you are maintaining are being modified, check this out!

@simahawk

Copy link
Copy Markdown
Contributor

Isn't this the same issue of #1009 ?

@RicardCForgeFlow

Copy link
Copy Markdown
Author

Isn't this the same issue of #1009 ?

Hello @simahawk
Not exactly. Here, AI explanation that helped me to understand:

image

As I understand it: #1009 is about errors that reach the runner as a plain OperationalError: they are retried, but max_retries is never applied. Here the error is wrapped in another exception (example: SignupError in auth_signup), so it is never retried at all.

@AlexPForgeFlow AlexPForgeFlow left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM! 👍

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants