mirror of
https://github.com/microsoft/BCQuality.git
synced 2026-08-06 09:26:52 +01:00
Adds 55 articles (plus 76 code samples) spanning four new domains and two existing domains, extracted from the internal Business Central review-agent prompt. Content was filtered against BCQuality's remedial-knowledge premise: each article encodes BC-specific behaviour, a CodeCop rule, a platform API semantic, or an anti-false-positive guideline that a capable LLM would otherwise get wrong. New domains: - privacy (11 articles): DataClassification inheritance semantics, the StrSubstNo-defeats-Error-telemetry-classification pitfall, Privacy Notice consent for outgoing requests, anti-false-positives for pages and in-memory data. - upgrade (11 articles): upgrade-codeunit structure, upgrade-tag lifecycle and registration, protected DB reads, DataTransfer for large datasets, InitValue semantics, enum-ordinal preservation, obsolete-workflow, first-install detection. - ui (9 articles): caption capitalization by phrase type, tooltip voice, teaching-tip vs tooltip, tour-tip conventions, character limits, banned terms, ampersand handling, title punctuation. - style (11 articles): label-suffix convention, API page naming, temporary-variable prefix, label properties (Comment/Locked), named invocations, FieldCaption in user messages, OptionCaption pairing, Error-parameter passing, `this` keyword, required parentheses, file naming. Gaps in existing domains: - performance (11 articles): production-scale table catalog (no row counts, per internal-data concern), anti-false-positive for bounded tables, guard-before-Get ordering, redundant-Get-in-OnAfterGetRecord, LockTable in read-only helpers, combined ModifyAll passes, writes in OnAfterGetRecord, SetLoadFields heuristics, temporary-table regressions, FlowField source-table widening, MaintainSQLIndex disabling SIFT. - security (2 articles): environment-specific hardcoded GUIDs, ValidateTableRelation=false on user input. Intentionally excluded: specific production P95 row-count numbers (aggregated internal telemetry); rewritten as categorical guidance on which tables to treat as production-scale without publishing sizes. All articles use `bc-version: [all]` (applies to every BC version, per the new schema sentinel). Validator passes with 0 errors / 0 warnings.
26 lines
1.5 KiB
Markdown
26 lines
1.5 KiB
Markdown
---
|
|
bc-version: [all]
|
|
domain: performance
|
|
keywords: [locktable, read-only, write-path, contention, helper]
|
|
technologies: [al]
|
|
countries: [w1]
|
|
application-area: [all]
|
|
---
|
|
|
|
# Split read-only and write paths so LockTable runs only when needed
|
|
|
|
## Description
|
|
|
|
LockTable takes an exclusive write lock on the affected table for the remainder of the transaction. In a helper that is called from many read-only sites and a few write sites, placing LockTable unconditionally at the top serializes every reader on every other reader's lock — the helper becomes a system-wide contention point. The correct shape is a conditional structure: try the read-only path first, and only fall through to LockTable when the code genuinely needs to modify the table.
|
|
|
|
## Best Practice
|
|
|
|
Factor the helper so readers return immediately without a lock and only writers reach the LockTable call. A common pattern: attempt `Rec.Get()` first; if it returns the row, exit with the value; otherwise LockTable and proceed with the Insert. Document the pattern in a comment on the helper so callers understand why the LockTable is inside a branch.
|
|
|
|
See sample: `split-read-only-and-write-paths-to-avoid-locktable.good.al`.
|
|
|
|
## Anti Pattern
|
|
|
|
A `GetOrCreate` helper that unconditionally calls `Rec.LockTable()` at the top, then Gets the row, then returns it. Every reader now blocks every other reader even though none of them intend to write. Under load the helper becomes the dominant bottleneck.
|
|
|
|
See sample: `split-read-only-and-write-paths-to-avoid-locktable.bad.al`.
|