bcquality/community/knowledge/error-handling/table-event-subscriber-rolls-back-whole-batch.md
Jeremy Vyska f5156c61de Add 15 community knowledge articles from BC Code Intel ingest
Ingests net-new /community knowledge from BC Code Intelligence, surviving
the admission test, gray-zone salvage, and dedup against the full corpus.

Domains: ui (6), error-handling (3), performance (2), upgrade (1),
appsource (1), security (1), telemetry (1). The two BC24 No. Series
migration drafts are merged into one article.

Adds good/bad AL samples for the clean-fit articles (error-handling,
performance, security, telemetry). UI and appsource remain knowledge-only.

Validator and knowledge-index checks pass (207 articles).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-01 11:02:48 +02:00

1.7 KiB

bc-version domain keywords technologies countries application-area
all
error-handling
table-events
oninsert
onmodify
ondelete
transaction
rollback
commit
batch
subscriber
al
w1
all

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 COMMITs, 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 COMMITs 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.