VGhellovg.sys
HomeProjectsBlogResume
HELLOVG SYSTEMS // CV TERMINALBUILD 86.09 // ONLINE
>_hellovg.sys/Vimal Govind Markkasseri

Enterprise software engineer specializing in reliable ERP systems, .NET modernization, SQL Server, and practical AI-assisted workflows.

All systems operational · Manama, Bahrain GMT+3

Navigation

  • >Home
  • >Projects
  • >Blog
  • >Resume
  • >RSS Feed

Connect

GitHubLinkedInXInstagramhey@hellovg.win

© 2026 Vimal Govind Markkasseri. Built with Next.js & Cloudflare Pages.

Press CtrlJ anytime for quick commands

~/blog
transactional-outbox-erp-events.md

title: "Reliable ERP Events: Where the Transactional Outbox Fits"

date: 2026-06-26

readingTime: 3 min read

tags: ["ERP", "Architecture", "Database", "Microservices"]

Reliable ERP Events: Where the Transactional Outbox Fits

June 26, 20263 min read
ERPArchitectureDatabaseMicroservices

Reliable ERP Events: Where the Transactional Outbox Fits

Imagine an invoice is saved successfully, but the process stops before notifying the reporting service. Finance sees the invoice. The dashboard does not. Retrying the entire invoice request could create another problem if it creates a second invoice.

This is the boundary I would examine before adding more messaging infrastructure to an ERP application.

Save the Intent Alongside the Business Record

The transactional outbox records the business change and the event to publish in the same database transaction. A separate worker publishes pending events and records delivery progress. This closes the gap between committing a record and remembering that another system needs to hear about it. Microsoft's outbox architecture guide describes the pattern and a Cosmos DB implementation.

For a relational ERP design, I would start with an invoice table and an outbox table sharing a transaction:

Begin transaction
  Save invoice
  Save InvoicePosted event with a stable event ID
Commit transaction

Publisher worker
  Claim a pending event
  Send it to the broker
  Record successful publication

The request can then report that the invoice was committed without claiming every downstream system has finished processing it.

Give Each Consumer a Duplicate Policy

Publication can succeed immediately before a worker crashes. On recovery, the same event may be sent again. An outbox does not make every downstream effect happen exactly once.

For an illustrative reporting consumer, I would store the processed event ID and update the report projection in one local transaction, with a uniqueness constraint protecting concurrent deliveries. An external email or payment requires its own duplicate-handling strategy because that effect is outside the local transaction.

Design the Support Screen Before the Dashboard

For this invoice workflow, my support view would show the invoice ID, event ID, creation time, attempt count, last failure category, and current delivery state. Sensitive payload fields would stay out of ordinary logs.

The most useful alert would be the age of the oldest pending event. A queue of ten items could be harmless during normal processing or a serious problem if those items have been waiting since yesterday.

I would also define who can replay an event, how replay is audited, and how incompatible payload versions are handled. If invoice changes must arrive in sequence, that ordering requirement needs an explicit design; parallel workers should not be assumed to preserve it.

Start With One Workflow

My first candidate would be a committed invoice feeding a reporting projection. I would deliberately stop the worker after publication, deliver a duplicate, and make the broker unavailable temporarily. The release criterion would be a recoverable, explainable state after each failure.

An outbox is useful when losing the notification matters. It also creates a queue that someone must operate. Both belong in the design discussion.

You might also like

2026-10-18

SQL Server 2025 Native Vector and JSON: Pragmatic ERP Search Without a Dedicated Vector DB

6 min read

2026-07-24

Caching ERP Dashboards Without Hiding Stale Data

3 min read

2026-08-21

Retries and Idempotency: Protecting Business Operations

3 min read
PreviousNext