Excellent thread - let me provide a comprehensive solution addressing all three focus areas.
MCO Number Uniqueness Check:
The root cause is the SDK’s auto-numbering mechanism lacking atomic operations during concurrent access. When multiple threads request MCO creation simultaneously, they can receive the same candidate number before database constraints validate uniqueness. Implement a distributed lock pattern or use database-level sequence generation to ensure true uniqueness at the source.
SDK Error Handling:
Your error handling needs to be proactive, not just reactive. Implement a three-tier approach:
private IManufacturingChangeOrder createMCOWithRetry(IAdmin admin, String desc) {
int maxRetries = 3;
for (int attempt = 0; attempt < maxRetries; attempt++) {
try {
synchronized(MCO_CREATION_LOCK) {
IAgileClass mcoClass = admin.getAgileClass("MCO");
IManufacturingChangeOrder mco = (IManufacturingChangeOrder) mcoClass.createObject();
mco.setValue(ChangeConstants.ATT_COVER_PAGE_DESCRIPTION, desc);
return mco;
}
} catch (DuplicateException e) {
if (attempt == maxRetries - 1) throw e;
Thread.sleep(50 + new Random().nextInt(150));
}
}
}
The synchronized block prevents local race conditions, while the retry loop with exponential backoff handles distributed conflicts. Log each retry attempt with correlation IDs for troubleshooting.
Automated Workflow Resilience:
Make your integration fault-tolerant by implementing:
- Circuit breaker pattern - temporarily halt MCO creation if error rate exceeds threshold
- Dead letter queue - route failed requests to a separate queue for manual review
- Idempotency tokens - include unique request IDs to prevent duplicate MCO creation on retries
- Health monitoring - track success rates and alert when they drop below acceptable levels
Additionally, review your auto-numbering scheme. Consider formats like MCO-{YYYY}{MM}{DD}-{SEQ} where SEQ resets daily, reducing collision probability. Configure adequate sequence padding (at least 6 digits) to handle high-volume periods.
For production stability, also tune these Agile server properties:
wt.method.server.maxThreads=75
wt.pom.dbcp.maxActive=100
wt.pom.dbcp.maxWait=180000
This configuration ensures sufficient resources for concurrent SDK operations. Monitor your database connection pool utilization - if you’re consistently hitting limits, scale up the pool size accordingly.
Finally, implement comprehensive logging that captures: thread ID, timestamp, MCO number attempted, success/failure status, and retry count. This telemetry is invaluable for identifying patterns in failures and optimizing your resilience strategy over time.