mirror of
https://github.com/microsoft/BCQuality.git
synced 2026-10-05 14:46:55 +01:00
A modal page does not behave like Confirm/StrMenu inside a write transaction: the platform refuses Page.RunModal (and Report/XmlPort .RunModal with a request page, and Codeunit.Run with its return value used) with a runtime error instead of holding the lock. The new article documents that guard - verified against Microsoft Learn (Codeunit.Run transaction semantics), microsoft/AL#5452, Microsoft's own Base Application (Commit(); Page.RunModal pattern), and a live reproduction on Business Central 26 quoted verbatim. avoid-user-prompts-inside- transactions.md keeps its scope to the prompts the platform does allow; "modal page" is removed from its list because that case is refused, not stalled. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
26 lines
1.5 KiB
Markdown
26 lines
1.5 KiB
Markdown
---
|
|
bc-version: [all]
|
|
domain: performance
|
|
keywords: [confirm, strmenu, dialog, transaction, lock, user-interaction]
|
|
technologies: [al]
|
|
countries: [w1]
|
|
application-area: [all]
|
|
---
|
|
|
|
# Do not hold locks while waiting for the user
|
|
|
|
## Description
|
|
|
|
A `Confirm`, `StrMenu`, or other user prompt issued from inside a write transaction stalls the transaction — and therefore every lock it holds — until the user responds. Per the upstream guidance, "Avoid user interactions (Confirm, StrMenu) inside transactions — they hold locks while waiting for user input." The wait is bounded only by the user; meanwhile other sessions block on whatever this transaction has acquired.
|
|
|
|
## Best Practice
|
|
|
|
Sequence the operation so user confirmation happens *before* any database write that takes a lock the prompt holds open. The shape is: ask the user → if confirmed, acquire locks and post. `if Confirm(...) then begin SalesHeader.LockTable(); SalesHeader.Get(DocNo); PostSalesOrder(SalesHeader); end;` keeps the lock window down to the work itself.
|
|
|
|
See sample: [`avoid-user-prompts-inside-transactions.good.al`](avoid-user-prompts-inside-transactions.good.al).
|
|
|
|
## Anti Pattern
|
|
|
|
`SalesHeader.LockTable(); SalesHeader.Get(DocNo); if Confirm('Post this order?') then ...;` — the lock is held for as long as the dialog is up. A user who steps away to lunch holds the lock for an hour, and every other session that touches that row blocks for the duration.
|
|
|
|
See sample: [`avoid-user-prompts-inside-transactions.bad.al`](avoid-user-prompts-inside-transactions.bad.al).
|