Skip to content

[17.0] queue_job: concurrent update exception on job state update #879

Closed as not planned

Description

@m3asmi

hi,
I found issue with latest version of queue_job '17.0.1.5.0'

 2026-01-15 16:33:37,264 2391938 ERROR tecnibo170 odoo.addons.queue_job.controllers.main: PG concurrency error (40001) while performing job. uuid=d665ad65-1df5-4679-8d59-dd33c41f9d72 func=imos.proadmin(15267,).create_sub_so() pid=2392431 

Traceback (most recent call last):

  File "/home/rachid/01_Workspace/odoo/custom/other_addons/queue_job/controllers/main.py", line 122, in runjob

    self._try_perform_job(env, job)

  File "/home/rachid/01_Workspace/odoo/custom/other_addons/queue_job/controllers/main.py", line 44, in _try_perform_job

    env.flush_all()

  File "/home/rachid/01_Workspace/odoo/servers/17/odoo/api.py", line 739, in flush_all

    self[model_name].flush_model()

  File "/home/rachid/01_Workspace/odoo/servers/17/odoo/models.py", line 6364, in flush_model

    self._flush(fnames)

  File "/home/rachid/01_Workspace/odoo/servers/17/odoo/models.py", line 6466, in _flush

    model.browse(ids)._write(vals)

  File "/home/rachid/01_Workspace/odoo/servers/17/odoo/models.py", line 4550, in _write

    cr.execute(SQL(

  File "/home/rachid/01_Workspace/odoo/servers/17/odoo/sql_db.py", line 335, in execute

    res = self._obj.execute(query, params)

          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

psycopg2.errors.SerializationFailure: could not serialize access due to concurrent update


2026-01-15 16:33:37,290 2391938 DEBUG tecnibo170 odoo.addons.queue_job.controllers.main: <Job d665ad65-1df5-4679-8d59-dd33c41f9d72, priority:10> postponed 

2026-01-15 16:33:37,291 2391941 DEBUG ? odoo.addons.queue_job.jobrunner.channels: job d665ad65-1df5-4679-8d59-dd33c41f9d72 properties changed, rescheduling it 

2026-01-15 16:33:37,291 2391941 DEBUG ? odoo.addons.queue_job.jobrunner.channels: job d665ad65-1df5-4679-8d59-dd33c41f9d72 marked pending in channel root.heavy(C:∞,Q:1,R:0,F:2) ```

resolved it using this code: queue_job/jobrunner/runnuer.py

    def _query_requeue_dead_jobs(self):
        return """
            UPDATE
                queue_job
            SET
                state=(
                    CASE
                        WHEN
                            max_retries IS NOT NULL AND
                            max_retries != 0 AND -- infinite retries if max_retries is 0
                            retry IS NOT NULL AND
                            retry>max_retries
                        THEN 'failed'
                        ELSE 'pending'
                    END),
                retry=(
                    CASE
                        WHEN state='started'
                        THEN COALESCE(retry,0)+1 ELSE retry
                    END),
                exc_name=(
                    CASE
                        WHEN
                            max_retries IS NOT NULL AND
                            max_retries != 0 AND -- infinite retries if max_retries is 0
                            retry IS NOT NULL AND
                            retry>max_retries
                        THEN 'JobFoundDead'
                        ELSE exc_name
                    END),
                exc_info=(
                    CASE
                        WHEN
                            max_retries IS NOT NULL AND
                            max_retries != 0 AND -- infinite retries if max_retries is 0
                            retry IS NOT NULL AND
                            retry>max_retries
                        THEN 'Job found dead after too many retries'
                        ELSE exc_info
                    END)
            WHERE
                id in (
                    SELECT
                        queue_job_id
                    FROM
                        queue_job_lock
                    WHERE
                        queue_job_id in (
                            SELECT
                                id
                            FROM
                                queue_job
                            WHERE
                                state = 'enqueued' -- CHANGED FROM IN ('enqueued', 'started')
                                AND date_enqueued <
                                (now() AT TIME ZONE 'utc' - INTERVAL '10 sec')
                        )
                    FOR UPDATE SKIP LOCKED
                )
            RETURNING uuid
            """```

Activity

  1. sbidoul commented on Jan 21, 2026

    @sbidoul
    Member

    Hello, the change you want to make is not immediately obvious. Could you try with #853 and #873 which also touch this area?

  2. github-actions commented on Jul 26, 2026

    @github-actions

    There hasn't been any activity on this issue in the past 6 months, so it has been marked as stale and it will be closed automatically if no further activity occurs in the next 30 days.
    If you want this issue to never become stale, please ask a PSC member to apply the "no stale" label.

  3. added
    stalePR/Issue without recent activity, it'll be soon closed automatically.
    on Jul 26, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugstalePR/Issue without recent activity, it'll be soon closed automatically.

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions