Skip to content

AL methods limited during write transactions (RunModal, Codeunit.Run) - #161

Open
Michael Dieringer (MichaelDieringer) wants to merge 6 commits into
microsoft:mainfrom
Curabis:community-contribution/runmodal-write-transaction-guard
Open

AL methods limited during write transactions (RunModal, Codeunit.Run)#161
Michael Dieringer (MichaelDieringer) wants to merge 6 commits into
microsoft:mainfrom
Curabis:community-contribution/runmodal-write-transaction-guard

Conversation

@MichaelDieringer

@MichaelDieringer Michael Dieringer (MichaelDieringer) commented Sep 8, 2026

Copy link
Copy Markdown

Summary

One new performance article, al-methods-limited-during-write-transactions.md, documenting the platform restriction behind the runtime error "The following AL methods are limited during write transactions because one or more tables will be locked: Form.RunModal, Codeunit.Run, Report.RunModal, XmlPort.RunModal." — one explicit line per method with its exact condition (Page.RunModal never; Report/XmlPort.RunModal only with the request page suppressed; Codeunit.Run only when the return value is unused), why the guard exists, and how to structure code so it never triggers.

Why the Microsoft layer: this is platform-enforced behavior, not a team convention. Verified against: Microsoft Learn (Codeunit.Run transaction semantics — "you must commit first"); a live reproduction on Business Central 26 (2026-09-07, Item.Insert() then Page.RunModal(Page::"Customer Card") — unrelated table — fails on the RunModal line; message quoted verbatim); Microsoft's own Base Application, which follows the Commit(); Page.RunModal(...) pattern in ActivityLog.Table.al, DocumentSendingProfile.Table.al, PaymentServiceSetup.Table.al and others; and microsoft/AL#5452 for the pre-2019 wording. Only the Codeunit.Run leg is documented on Learn; the RunModal legs exist only as the runtime error text — which is exactly why an agent gets this wrong without the file.

Relationship to existing articles: codeunit-run-requires-prior-commit-inside-transaction.md keeps ownership of the Codeunit.Run leg (cross-referenced, not duplicated). avoid-user-prompts-inside-transactions.md keeps the prompts the platform allows inside a write transaction (Confirm/StrMenu — which therefore silently hold locks); the two words "modal page" are removed from its list, because that case is refused with a runtime error, not stalled.

Wiring: al-performance-review.md gains Page.RunModal/Report.RunModal/XmlPort.RunModal/UseRequestPage tokens and one deterministic worklist cue with exclusions (RunModal before every write; request page suppressed), routing Codeunit.Run in that position to its existing owner — per #155's coverage contract.

Samples reference real objects only: page 428 "Shipping Agents", table 291 "Shipping Agent" (Code[10]), Sales Header fields 21 "Shipment Date" and 105 "Shipping Agent Code".

Test plan

  • validate_frontmatter.py --root . — 0 errors, 0 warnings
  • Build-KnowledgeIndex.ps1 — 301 articles, deterministic
  • Test-ReviewFixtures.ps1 — 34 cases / 17 leaf domains
  • CLA signed on this PR (company="CURABIS ApS")
  • Domain owner review (microsoft/knowledge/performance/)

… 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>
Message runs asynchronously - it is queued and shown when the calling
method ends or another method requests input - so it never pauses the
transaction and holds no lock. Only Confirm and StrMenu wait for the
user.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…method

Mirrors the structure of the platform's own error message so the
Report.RunModal and XmlPort.RunModal request-page exceptions are
visible at a glance instead of buried in prose.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
"AL methods limited during write transactions: commit before RunModal
and Codeunit.Run" - so a developer or agent searching for the runtime
error text lands on the one article that covers all four restricted
methods. Slug and sample stems renamed to match; keywords gain the
error's own phrase and the legacy Form.RunModal name it still uses.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Adds Page.RunModal / Report.RunModal / XmlPort.RunModal / UseRequestPage
to the extracted-token list and one deterministic worklist cue with
exclusions, so the article is selected from the RunModal call itself
rather than only via a co-located Commit/Modify token. Codeunit.Run in
that position is routed to its existing owner article.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
@MichaelDieringer

Copy link
Copy Markdown
Author

@microsoft-github-policy-service agree company="CURABIS ApS"

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.

1 participant