bcquality/microsoft/knowledge/performance/avoid-user-prompts-inside-transactions.md
Michael Dieringer 2a4cb856ef Add runmodal-is-not-allowed-inside-write-transactions.md; drop "modal page" from the prompts article
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>
2026-09-21 21:56:30 +02:00

1.5 KiB

bc-version domain keywords technologies countries application-area
all
performance
confirm
strmenu
dialog
transaction
lock
user-interaction
al
w1
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.

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.