When Should You Send Messages in a Transaction? Real‑World Order Processing Insights
This article examines the trade‑offs of sending messages before, during, or after database persistence in order‑creation workflows, explores transaction‑message patterns, half‑message checks, and message‑table strategies, and offers practical guidance for building reliable backend messaging systems.
The author reflects on the lack of a universal best practice for sending messages in business code, emphasizing the need for fault‑tolerant designs based on specific business contexts.
Problem Scenario
A developer in an order‑processing team faced uncertainty about where to place the message‑sending call in the transaction flow:
try {
transactionTemplate.start(); // location 1
orderManager.createOrder(order);
// location 2
messageProducer.send(buildOrderCreatedMsg(order)); // send order‑created message
transactionTemplate.commit(); // location 3
} catch (Exception e) {
transactionTemplate.rollback();
}The question was whether to send the message at position 1, 2, or 3.
Analysis of the Three Positions
Send before persistence (position 1) : The order creation may take up to several seconds and can fail; sending a message here risks notifying a non‑existent order.
Send after business logic but before commit (position 2) : The order is created, but the transaction is not yet committed, so a failure or hang in the messaging path can block the commit.
Send after commit (position 3) : Guarantees the order exists, but occasional network errors or process restarts can cause lost messages, as observed in production.
Using Transactional Messages
To address these issues, the author adopted a transactional‑message approach:
try {
transactionTemplate.start();
messageTransactionProducer.send(buildOrderCreatedMsg(order), new TransactionExecutor(transactionTemplate){
@Override
public TransactionStatus execute(Message msg) {
orderManager.createOrder(order);
return TransactionStatus.CommitTransaction;
}
});
} catch (Exception e) {
transactionTemplate.rollback();
}
// Half‑message check implementation
public class OrderTransactionCheckerImpl implements TransactionChecker {
@Override
public TransactionStatus check(Message msg) {
if (orderManager.isOrderExist(getOrderId(msg))) {
return TransactionStatus.CommitTransaction;
} else {
// If the check occurs within 20 s of sending, treat as unknown (transaction may still be pending)
if (new Date().getTime() - msg.getSendTime() > 20000) {
return TransactionStatus.RollbackTransaction;
} else {
return TransactionStatus.Unknown;
}
}
}
}Adding a 20‑second grace period for unknown status prevented premature rollbacks when the database was temporarily unavailable.
Message‑Table Alternative
Another simple solution is to write a record to a dedicated message table within the same transaction as the order:
try {
transactionTemplate.start();
orderManager.createOrder(order);
miniBus.addMsg(buildOrderCreatedMsg(order)); // insert a half‑message record
transactionTemplate.commit();
} catch (Exception e) {
transactionTemplate.rollback();
}A background scanner reads the table, processes pending messages, and deletes records after successful handling, ensuring strong consistency between business data and messages.
Key Takeaways
There is no single “best practice”; engineers must balance latency, failure handling, and system complexity. Important considerations include:
Ensuring order existence checks read from the primary database.
Defining acceptable message‑send timeouts and business reactions to large‑scale timeouts.
Assessing whether occasional message loss is tolerable and planning compensation mechanisms.
Verifying idempotency on the consumer side and the feasibility of bulk re‑delivery.
Ultimately, proactive fault‑tolerance design, rather than a silver‑bullet solution, is essential for stable message delivery.
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
Alibaba Cloud Developer
Alibaba's official tech channel, featuring all of its technology innovations.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
