I’ll address all three aspects of your batch processing issue:
1. Batch Job Concurrency:
Your 15-minute schedule with 18-22 minute execution times creates overlapping jobs that compete for the same order records. Implement a job lock mechanism:
if (isJobAlreadyRunning("OrderApprovalBatch")) {
logger.warn("Previous batch still running, skipping");
return;
}
Also increase your schedule interval to 20 minutes or implement a completion-based trigger instead of time-based. This prevents concurrent batch execution entirely.
2. Workflow Status Updates:
Your status updates are failing because you’re validating and updating in separate transactions. Restructure to use atomic operations:
transaction.begin();
Order order = fetchOrderWithLock(orderId);
if (order.getStatus() == "PENDING") {
validateAndApprove(order);
order.setStatus("APPROVED");
transaction.commit();
}
The key is fetching with a lock (SELECT FOR UPDATE) and committing immediately after status change. Don’t hold locks during validation - do validation first, then acquire lock only for the update.
3. Order Data Validation:
Move validation outside the transaction boundary to avoid long-running locks:
// Pseudocode - Optimized batch processing flow:
1. Query all PENDING orders without locks
2. Perform validation checks on entire batch (approval rules, credit limits, inventory)
3. Create list of valid order IDs ready for approval
4. For each valid order (in chunks of 50):
a. Begin transaction
b. Fetch order with exclusive lock
c. Recheck status is still PENDING (double-check pattern)
d. Update status to APPROVED
e. Commit transaction immediately
5. Log any orders that failed recheck for next batch cycle
// This minimizes lock hold time
Implement batch chunking with proper error handling:
- Process 100 orders per chunk with commit between chunks
- Add retry logic for deadlock exceptions (max 3 retries with exponential backoff)
- Skip orders that are locked by other processes rather than failing entire batch
- Maintain a processing timestamp to identify stuck orders for cleanup
For your stuck orders in PROCESSING state, create a cleanup job that runs hourly to reset orders stuck for more than 30 minutes. This handles edge cases where locks weren’t properly released due to job failures.
The reason manual approval works is single-record processing with immediate exclusive locks and no validation overhead. Your batch needs to mimic this pattern but at scale with proper concurrency controls.
This draft is based on general Infor CloudSuite knowledge. It has not been verified against your specific version and environment. Practitioners: verify the steps and share your experience below.