mirror of
https://github.com/microsoft/BCQuality.git
synced 2026-10-06 07:06:54 +01:00
Promotes rules that are already published in community/ to custom/knowledge/, so they load at every session start instead of only on keyword relevance. Each file carries extends: pointing back to its community source. Passed Immanuel's four-test Categorical Imperative validation on 2026-08-07.
21 lines
1.8 KiB
Markdown
21 lines
1.8 KiB
Markdown
---
|
|
bc-version: [all]
|
|
domain: error-handling
|
|
keywords: [table-events, oninsert, onmodify, ondelete, transaction, rollback, commit, batch, subscriber]
|
|
technologies: [al]
|
|
countries: [w1]
|
|
application-area: [all]
|
|
extends: community/error-handling/table-event-subscriber-rolls-back-whole-batch.md
|
|
---
|
|
# A Throw In A Table-Event Subscriber Rolls Back The Whole Batch
|
|
|
|
> Contributions welcome — open a PR to refine or extend this article.
|
|
|
|
## Description
|
|
Table-trigger event subscribers (`OnAfterInsertEvent`, `OnAfterModifyEvent`, `OnAfterDeleteEvent`, and their `OnBefore` counterparts) execute synchronously inside the transaction of the write that fired them. Because AL runs on a single implicit transaction with no per-record savepoint, an error raised in such a subscriber rolls back **all work since the last `COMMIT`** — not just the record that triggered it. In a batch loop with no intermediate `COMMIT`s, a single failing record discards the entire batch. The intuition that subscriber validation fails only the current record is wrong on the BC platform.
|
|
|
|
## Best Practice
|
|
Decide the failure granularity deliberately. If a batch must continue past individual failures, do not throw from the table-event subscriber — collect the error (for example via `ErrorInfo`/collectible errors) and let the loop continue, or isolate each record's work behind a `Codeunit.Run` / `if Codeunit.Run() then` boundary so its failure rolls back only that record. Insert intermediate `COMMIT`s only with full awareness of the durability trade-off.
|
|
|
|
## Anti Pattern
|
|
Putting `Error`/`TestField`/`FieldError` validation inside a table-event subscriber and assuming it rejects just the offending record during bulk processing. The first failure unwinds every uncommitted record in the run, turning a one-row data problem into a whole-batch rollback.
|