Conversation
|
Hi @sebastienbeau, @hparfr, |
grindtildeath
left a comment
There was a problem hiding this comment.
thanks for the PR, I've seen it's WIP but here's a small comment.
However, did you check #3739 yet?
| ): | ||
| raise_exception = True | ||
| if raise_exception: | ||
| if raise_exception and not no_rollback: |
There was a problem hiding this comment.
Nitpicking a little bit, but couldn't you name the function _exceptions_rollback and default to True instead of using a negative and having a double negation here?
There was a problem hiding this comment.
Good point, done: _exceptions_rollback() is true by default and the double negation is gone.
The context key keeps the negative name (base_exception_no_rollback), so that not setting it means the current behavior.
Add _exceptions_rollback(), true by default: it is false for the main
records listed in the base_exception_no_rollback context ({model: ids}),
and then the exceptions are stored in the ongoing transaction and
detect_exceptions() does not raise.
Callers that already wrote on those records in the transaction cannot
use the second cursor: it waits forever on the row lock held by the
ongoing transaction.
5ce68b7 to
52154a6
Compare
|
Thanks for the review, and for pointing at #3739 — I had missed it, it was opened a few hours before this one. The two PRs solve different halves of the problem and do not overlap:
So #3739 alone would turn the portal hang into a lost signature after 2 seconds, and this PR alone leaves the backend hang unfixed. Together they cover both. They compose cleanly: with the context of this PR set, The consumer is OCA/sale-workflow#4600, where |
Follow-up of #3590.
Problem
detect_exceptions()stores the exceptions through a second cursor, so the ongoing transaction can be rolled back. When the ongoing transaction already wrote on the main records, the second cursor waits on the row lock that the same thread holds: the request never ends (untillimit_time_realkills the worker).Real case (Odoo 18,
sale_exception): signing a quotation in the customer portal.portal_quote_acceptwrites the signature and flushes, then_validate_order()→action_confirm()→detect_exceptions().pg_stat_activityshows the main connectionidle in transactionand the second one waiting onLock / transactionidforUPDATE sale_order SET main_exception_id ....Change
_exceptions_rollback(), true by default. It is false for the main records listed in the contextbase_exception_no_rollback={model: ids}, and thendetect_exceptions()stores the exceptions with the current cursor and does not raiseBaseExceptionError. The caller decides with_must_raise_exception_after_detection().The flag is scoped by model and ids on purpose: other exception models reached from the same call (e.g. purchase or stock exceptions triggered by the sale confirmation) keep the default behavior.
Nothing changes when the context key is not set.
The consumer is the sale-workflow PR for
sale_exception, which will reference this one.Relation with #3739
The two PRs solve different halves of the problem. #3739 fixes the hang itself, for any caller that wrote earlier in the transaction, and still raises
BaseExceptionErrorso the backend popup keeps working. This PR does not fix that hang: with it applied, confirming an order from the backend after an earlier write on the same row still waits on the row lock forever. What it adds is a way for the caller to ask for no rollback, which #3739 does not cover, and which the portal needs to keep the signature it already wrote.They compose: with this context set,
new_envisself.env, which #3739 writes with directly. Both touch the same lines ofdetect_exceptions(), so whichever lands second needs a rebase. Happy to rebase this one on top of #3739.