Skip to content

[16.0][FIX] connector_sapb1: enable allow_commit on export_record job funct…#895

Open
deeniiz wants to merge 2 commits into16.0from
16.0-fix-connector_sapb1-allow_commit_export_record
Open

[16.0][FIX] connector_sapb1: enable allow_commit on export_record job funct…#895
deeniiz wants to merge 2 commits into16.0from
16.0-fix-connector_sapb1-allow_commit_export_record

Conversation

@deeniiz
Copy link
Copy Markdown
Collaborator

@deeniiz deeniiz commented Apr 24, 2026

…ions

bind_export in connector_extension performs cr.commit() to persist the binding immediately after the SAP HTTP PATCH succeeds. This is intentional: it prevents duplicate addresses being created in SAP on job retry (when the adapter's -2035 counter would increment AddressName to "(2)", "(3)" etc. for the same partner on each retry attempt).

Since queue_job 16.0.2.13.2 (OCA/queue#892), the _prevent_commit guard raises RuntimeError on any cr.commit() inside a job. Setting allow_commit =True on the Job Function makes perform() run in a temporary env with a separate DB cursor: the commit is real but does not release the main cursor's queue_job row-lock, so there is no double execution risk.

Post-migration updates the existing auto-created queue.job.function records for:

  • sapb1.binding
  • sapb1.res.partner
  • sapb1.sale.order
  • sapb1.sale.order.line
  • sapb1.product.product

Refs: https://github.com/OCA/queue/wiki/Upgrade-warning:-commits-inside-jobs

@codecov
Copy link
Copy Markdown

codecov Bot commented Apr 24, 2026

Codecov Report

❌ Patch coverage is 0% with 6 lines in your changes missing coverage. Please review.
✅ Project coverage is 43.75%. Comparing base (20d034b) to head (623c780).
⚠️ Report is 1 commits behind head on 16.0.

Files with missing lines Patch % Lines
connector_extension/models/binding/binding.py 0.00% 6 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             16.0     #895      +/-   ##
==========================================
- Coverage   44.28%   43.75%   -0.53%     
==========================================
  Files         317      325       +8     
  Lines        6294     6470     +176     
  Branches     1000     1011      +11     
==========================================
+ Hits         2787     2831      +44     
- Misses       3486     3618     +132     
  Partials       21       21              

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

…ions

bind_export in connector_extension performs cr.commit() to persist the
binding immediately after the SAP HTTP PATCH succeeds. This is intentional:
it prevents duplicate addresses being created in SAP on job retry (when
the adapter's -2035 counter would increment AddressName to "(2)", "(3)"
etc. for the same partner on each retry attempt).

Since queue_job 16.0.2.13.2 (OCA/queue#892), the _prevent_commit guard
raises RuntimeError on any cr.commit() inside a job. Setting allow_commit
=True on the Job Function makes perform() run in a temporary env with a
separate DB cursor: the commit is real but does not release the main
cursor's queue_job row-lock, so there is no double execution risk.

Post-migration updates the existing auto-created queue.job.function
records for:
  - sapb1.binding
  - sapb1.res.partner
  - sapb1.sale.order
  - sapb1.sale.order.line
  - sapb1.product.product

Refs: https://github.com/OCA/queue/wiki/Upgrade-warning:-commits-inside-jobs

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@deeniiz deeniiz force-pushed the 16.0-fix-connector_sapb1-allow_commit_export_record branch from 054ecba to 22d2ae3 Compare April 24, 2026 11:50
…in export entry-points

When a queue.job.function has allow_commit=True, queue_job 16.0's Job.in_temporary_env()
opens a new DB cursor and switches self.recordset.env to it. However, args passed to
the job method (backend_record, relation) keep the outer cursor — they were
deserialized from the queue.job's args field with the runner's env, and queue_job
does NOT re-bind them to the temporary env.

When binding.export_record(backend_record, relation) calls
backend_record.work_on(self._name), the resulting WorkContext.env returns
self.collection.env (component/core.py:271-277) — i.e. the OUTER cursor that has
the _prevent_commit monkey-patch applied. binder.bind_export() then commits via
self.env.cr.commit() and hits the forbidden_commit guard, so allow_commit=True alone
does NOT take effect for export entry-points whose flow ends in bind_export.

Fix: rebind backend_record (and relation) to a new env that copies the arg's
ORIGINAL env (preserving uid, su, context) and only swaps cr to self.env.cr —
the temporary cursor opened by Job.in_temporary_env(). This is the same pattern
queue_job itself uses internally (env(cr=new_cr)) and is minimally invasive: it
only changes the cursor, leaving the user/su/context that were captured at
enqueue time intact. Idempotent when self.env.cr already equals the arg's cr
(calls outside of a queue job).

Scope: only export entry-points need this. Imports do not commit — bind_import
does not call cr.commit() (was removed in 22c9fb2) — so they never hit the
forbidden_commit guard and don't need allow_commit=True nor the cursor propagation.

Verified against Novolux production task #2539: queue.job 9434462
(<sapb1.sale.order>.export_record, allow_commit=true) was still failing with
RuntimeError("Commit is forbidden in queue jobs") at binder.py:315 because
backend_record arrived on the outer cursor.
@eantones
Copy link
Copy Markdown
Member

eantones commented Apr 28, 2026

Supersedes #893.

#893 removed cr.commit() from bind_export and relied solely on _retry_unique_violation for race protection. That approach was rejected because it broke the eager-commit anti-orphan guarantee: if the job fails after SAP has already created the external record, rollback loses the binding and the next retry creates a duplicate in SAP.

This PR keeps the eager commit at binder.py:315 intact and instead activates the official OCA toggle allow_commit=True on the SAP B1 export queue.job.function records — the supported escape hatch added in OCA/queue#910 (commit f2bfda90, merged 2026-04-09). It runs the job on a separate cursor opened by Job.in_temporary_env(), so the commit is real but does not release the queue_job row-lock on the main cursor.

The latest commit 623c7809 adds a cursor-rebind workaround at connector_extension/models/binding/binding.py (4 export entry-points) for an undocumented limitation of in_temporary_env(): it only rebinds self.recordset.env to the new cursor, not the args. Without manual rebind, backend_record.work_on() builds a WorkContext on the outer cursor with _prevent_commit patched, so binder.bind_export()'s commit still raised RuntimeError("Commit is forbidden in queue jobs") despite allow_commit=True being set. This limitation is acknowledged by guewen (queue_job maintainer) in OCA/queue#889 but is not documented in the OCA wiki upgrade-warning page and has no tests in queue_job. See the detailed code comment at binding.py::export_data for the full rationale.

Verified in production after first deployment of this PR's earlier commits: queue.job 9434462 (<sapb1.sale.order>.export_record, allow_commit=true verified in DB) was still failing with the exact same error at binder.py:315 until the cursor-rebind commit was applied.

@guewen
Copy link
Copy Markdown

guewen commented Apr 28, 2026

Hi @eantones

This limitation is acknowledged by guewen (queue_job maintainer) in OCA/queue#889 but is not documented in the OCA wiki upgrade-warning page and has no tests in queue_job

Fyi I was not aware of the issue with arguments using another env that need to be rebound to the inner env. This may be something to be adressed in queue job, feel free to report

@eantones
Copy link
Copy Markdown
Member

Hi @guewen, thanks for the reply — much appreciated. We'll open an issue on OCA/queue and link it back here.

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants