Field apps were deadlocking the MySQL core on synchronous writes. We re-architected ingestion as idempotent Laravel queue workers with per-shipment locks.
Mobile/desktop scans hit REST → multi-table MySQL updates in one HTTP request. Peak freight hours caused row locks on shipments, sync backlogs, and dropped packets between field and core.
API validates, enqueues, returns 202 Accepted. Workers own joins, billing hooks, and cross-border status. Monotonic sequence per shipment prevents MY/SG drift.
| Option | Failure mode | Our fix |
|---|---|---|
| Sync REST | Deadlocks on batch scans | Single-writer job per shipment ID |
| Dual-write hubs | Cross-border drift | Event log + ordered propagation |
| SPA → DB | No back-pressure | Rate limits + scale workers on depth |
ProcessShipmentScan::dispatch($payload)
->onQueue('scans')->afterCommit();
return response()->json(['status' => 'queued'], 202);
// Worker: lockForUpdate on shipments, ordered table locks
Niaga Prestasi / TLMS programme. Metrics from production monitoring.