Chapter 19 Key Takeaways: IBM MQ for COBOL
Threshold Concept
Messaging decouples time, not just space. MQ doesn't just let systems communicate without knowing each other's location (spatial decoupling). It lets them communicate without operating at the same time (temporal decoupling). A sender puts a message at 2:00 PM; the receiver picks it up whenever it's ready — seconds, minutes, or hours later. This is why messages must be persistent, why transactional coordination matters, and why dead letter queues need monitoring. The queue is a contract between the present and the future.
Core Concepts
-
Point-to-point integration creates four types of coupling — temporal, spatial, format, and capacity. MQ addresses all four. The most important is temporal: systems no longer need to be running simultaneously.
-
Queue managers own everything. A queue manager is the core MQ server. It owns queues, manages connections, handles persistence, coordinates transactions, and controls security. On z/OS, it runs as its own subsystem with its own address spaces.
-
Know your queue types. Local queues store messages. Remote queue definitions route messages to other queue managers. Transmission queues hold messages in transit. Dead letter queues catch undeliverable messages. Model queues are templates for dynamic queues. Alias queues provide alternate names.
-
The MQI is small but must be used correctly. About a dozen verbs cover everything. The critical discipline: check the completion code and reason code after every single MQI call. No exceptions.
-
Message patterns determine architecture. Fire-and-forget (datagram) for decoupled, asynchronous flows. Request/reply for synchronous-style interactions. Pub/sub for one-to-many distribution. Choose the pattern before you write the first line of code.
-
Transactional messaging is MQ's killer feature for enterprise systems. MQPMO-SYNCPOINT makes an MQPUT part of the CICS/DB2 unit of work. Two-phase commit via RRS guarantees that either a DB2 update and an MQ message both commit or both roll back. This eliminates an entire class of data consistency bugs.
-
The backout counter prevents poison message loops. When a message causes repeated processing failures, the backout counter increments with each rollback. When it hits the threshold, route the message to the backout queue. Never let a poison message loop forever.
-
Shared queues provide the highest availability on z/OS. Stored in the Coupling Facility, shared queues are accessible by all queue managers in the Queue Sharing Group. Zero failover delay. Zero message loss. Required for critical payment flows.
Production Rules
-
Every MQI call gets error handling. Completion code and reason code. No exceptions. The day you skip the check is the day the queue fills up and you don't notice for 4 hours.
-
Use MQPMO-SYNCPOINT for financial transactions. If you're updating a database and putting a message, they must be in the same unit of work. Non-syncpoint puts in financial systems are bugs waiting to happen.
-
Use MQPMO-FAIL-IF-QUIESCING on every open and put. Your program should respect queue manager shutdown signals. An operation that hangs during planned maintenance creates an unplanned incident.
-
Persistent messages for anything you can't afford to lose. That's almost everything in banking and insurance. The log I/O cost is the price of reliability.
-
Size your buffers for the maximum, not the average. The MQGET buffer should handle the largest possible message for that queue. Handle truncation explicitly if you can't size for maximum.
-
The DLQ is an ICU, not a trash can. Every message in the DLQ is a failed business transaction. Monitor it. Process it. Resolve every message. If your DLQ depth is growing, something is broken.
-
Set message expiry for request/reply. Stale replies accumulate if you don't expire them. For a 30-second timeout, set expiry to 300 (30 seconds * 10 tenths per second).
-
Monitor queue depth trends, not just absolute depth. A queue at 10,000 that was at 100 yesterday is a problem. A queue at 10,000 that's always at 10,000 is normal. Trend matters more than threshold.
Common Mistakes
| Mistake | Consequence | Fix |
|---|---|---|
| Not checking CC/RC after MQI calls | Silent failures, data loss | EVALUATE block after every call |
| Non-persistent messages for financial data | Message loss on QM restart | Always MQPER-PERSISTENT |
| No SYNCPOINT on puts that pair with DB2 updates | Data consistency failures | MQPMO-SYNCPOINT, always |
| Fixed buffer size without truncation handling | MQGET fails for large messages | Size for MAXMSGL or handle 2080 |
| No backout counter check | Poison message loops | Check MQMD-BACKOUTCOUNT before processing |
| No DLQ monitoring | Failed transactions go unnoticed | Alert on DLQ depth > 0 |
| TRIGTYPE(EVERY) on high-volume queues | CICS region overload | Use TRIGTYPE(FIRST) for high volume |
| Not setting message expiry on replies | Reply queue fills with stale messages | Set appropriate MQMD-EXPIRY |
Key Reason Codes to Memorize
| Code | Name | What to Do |
|---|---|---|
| 0 | MQRC-NONE | Success — continue |
| 2033 | MQRC-NO-MSG-AVAILABLE | Normal — exit get loop |
| 2035 | MQRC-NOT-AUTHORIZED | Security issue — log and abend |
| 2053 | MQRC-Q-FULL | Retry with backoff, alert ops |
| 2009 | MQRC-CONNECTION-BROKEN | Reconnect or abend |
| 2161 | MQRC-Q-MGR-QUIESCING | Clean shutdown |
| 2080 | MQRC-TRUNCATED-MSG-FAILED | Buffer too small — handle explicitly |
| 2003 | MQRC-BACKED-OUT | UOW rolled back — retry or escalate |
Architecture Decision Framework
When designing MQ into a COBOL system, answer these questions in order:
- What are the message flows? Map every system-to-system communication path.
- What pattern does each flow need? Datagram, request/reply, or pub/sub?
- What are the SLAs? Latency, throughput, availability.
- What's the failure mode for each flow? What happens when the receiver is down? When the queue is full? When the message is invalid?
- What's the HA requirement? Clustering for most flows, shared queues for critical zero-loss flows.
- What's the transactional boundary? Which operations must be atomic? Where do you commit?
- What's the monitoring strategy? Queue depth, DLQ, channel status, message age.
Looking Ahead
This chapter gave you MQ fundamentals — the architecture, the API, the patterns, the transactional model. Chapter 20 builds on this with advanced patterns: message sequencing for ordered processing, message grouping for batch-in-messaging, and complex request/reply choreographies where multiple services collaborate to process a single business transaction. Chapter 21 takes MQ beyond the mainframe, using it as the bridge between COBOL systems and REST APIs, microservices, and cloud platforms.