In this section, the logic of the Sale business transaction is changed so that:
Figure 26 shows, in schematic form, the Sale example application when compensation actions are included.
Figure 27 shows, in COBOL pseudocode, the Sale root activity, modified to include compensation actions. The changes are in bold text.
Identification Division.
Program-id. SAL002.
Environment Division.
Data Division.
Working-Storage Section.
01 RC pic s9(8) comp.
01 Process-Name pic x(36).
01 Event-Name pic x(16).
88 DFH-Initial value 'DFHINITIAL'
88 Delivery-Complete value 'Delivry-Complete'.
88 Delivery-Confirmed value 'Delivry-Confirmd'.
88 Invoice-Complete value 'Invoice-Complete'.
88 Payment-Due value 'Payment-Due'.
88 Payment-Complete value 'Payment-Complete'.
88 Reminder-Expired value 'Remindr-Expired'.
88 Reminder-Complete value 'Remindr-Complete'.
01 Sale-Container pic x(16) value 'Sale'.
01 Order-Container pic x(16) value 'Order'.
01 Order-Buffer pic x(..).
01 Delivery-Container pic x(16) value 'Delivery'.
01 Delivery-Buffer pic x(..).
01 Confirm-Container pic x(16) value 'Confirm'.
01 Confirm-Buffer pic x(..).
01 Invoice-Container pic x(16) value 'Invoice'.
01 Invoice-Buffer pic x(..).
01 Reminder-Container pic x(16) value 'Reminder'.
01 Status pic x(16).
Linkage Section.
01 DFHEIBLK.
.
Procedure Division.
Begin-Process.
.
EXEC CICS RETRIEVE REATTACH EVENT(Event-Name)
RESP(RC) END-EXEC
.
If RC NOT = DFHRESP(NORMAL)
.
End-If.
.
Evaluate True
When DFH-Initial
Perform Initial-Activity
Perform Order-Activity
Perform Order-Response
Perform Delivery-Activity
When Delivery-Complete
Perform Delivery-Response
Perform Delivery-Confirmation
When Delivery-Confirmed
Perform Confirm-Response
Perform Invoice-Activity
When Invoice-Complete
Perform Invoice-Response
Perform Payment-Activity
When Payment-Due
Perform Payment-Due-Response
When Payment-Complete
Perform Payment-Response
When Reminder-Expired
Perform Reminder-Expired-Response
When Reminder-Complete
Perform Reminder-Response
When Other
.
End Evaluate.
.
EXEC CICS RETURN END-EXEC
.
Initial-Activity.
.
EXEC CICS ASSIGN PROCESS(Process-Name)
RESP(data-area) RESP2(data-area) END-EXEC
.
Order-Activity.
.
EXEC CICS DEFINE ACTIVITY('Order')
TRANSID('SORD')
PROGRAM('ORD001')
RESP(data-area) RESP2(data-area) END-EXEC
.
EXEC CICS PUT CONTAINER(Sale-Container)
ACTIVITY('Order') FROM(Process-Name)
RESP(data-area) RESP2(data-area) END-EXEC
.
EXEC CICS LINK ACTIVITY('Order')
RESP(data-area) RESP2(data-area) END-EXEC
.
Order-Response.
.
EXEC CICS CHECK ACTIVITY('Order') COMPSTATUS(status)
RESP(RC) RESP2(data-area) END-EXEC
.
If RC NOT = DFHRESP(NORMAL)
.
End-If.
.
If status NOT = DFHVALUE(NORMAL)
.
End-If.
.
.
Delivery-Activity.
.
EXEC CICS DEFINE ACTIVITY('Delivery')
TRANSID('SDEL')
PROGRAM('DEL001')
EVENT('Delivry-Complete')
RESP(data-area) RESP2(data-area) END-EXEC
.
EXEC CICS GET CONTAINER(Order-Container)
ACTIVITY(Order-Container) INTO(Order-Buffer)
RESP(data-area) RESP2(data-area) END-EXEC
.
EXEC CICS PUT CONTAINER(Order-Container)
ACTIVITY('Delivery') FROM(Order-Buffer)
RESP(data-area) RESP2(data-area) END-EXEC
.
EXEC CICS RUN ACTIVITY('Delivery')
ASYNCHRONOUS
RESP(data-area) RESP2(data-area) END-EXEC
.
Delivery-Response.
.
EXEC CICS CHECK ACTIVITY('Delivery') COMPSTATUS(status)
RESP(RC) RESP2(data-area) END-EXEC
.
If RC NOT = DFHRESP(NORMAL)
.
End-If.
.
If status NOT = DFHVALUE(NORMAL)
.
End-If.
.
Delivery-Confirmation.
.
EXEC CICS DEFINE ACTIVITY('Confirm')
TRANSID('FCON')
PROGRAM('CON001')
EVENT('Delivry-Confirmd')
RESP(data-area) RESP2(data-area) END-EXEC
.
EXEC CICS GET CONTAINER(Deliver-Container)
ACTIVITY('Delivery') INTO(Delivery-Buffer)
RESP(data-area) RESP2(data-area) END-EXEC
.
EXEC CICS PUT CONTAINER(Deliver-Container)
ACTIVITY('Confirm') FROM(Delivery-Buffer)
RESP(data-area) RESP2(data-area) END-EXEC
.
EXEC CICS RUN ACTIVITY('Confirm')
ASYNCHRONOUS
RESP(data-area) RESP2(data-area) END-EXEC
.
Confirm-Response.
.
EXEC CICS CHECK ACTIVITY('Confirm') COMPSTATUS(status)
RESP(RC) RESP2(data-area) END-EXEC
.
If RC NOT = DFHRESP(NORMAL)
.
End-If.
.
If status NOT = DFHVALUE(NORMAL)
.
End-If.
.
Invoice-Activity.
.
EXEC CICS DEFINE ACTIVITY('Invoice')
TRANSID('SINV')
EVENT('Invoice-Complete')
RESP(data-area) RESP2(data-area) END-EXEC
.
EXEC CICS GET CONTAINER(Confirm-Container)
ACTIVITY('Confirm') INTO(Confirm-Buffer)
RESP(data-area) RESP2(data-area) END-EXEC
.
EXEC CICS PUT CONTAINER(Confirm-Container)
ACTIVITY('Invoice') FROM(Confirm-Buffer)
RESP(data-area) RESP2(data-area) END-EXEC
.
EXEC CICS RUN ACTIVITY('Invoice')
ASYNCHRONOUS
RESP(data-area) RESP2(data-area) END-EXEC
.
Invoice-Response.
.
EXEC CICS CHECK ACTIVITY('Invoice') COMPSTATUS(status)
RESP(RC) RESP2(data-area) END-EXEC
.
If RC NOT = DFHRESP(NORMAL)
.
End-If.
.
If status NOT = DFHVALUE(NORMAL)
.
End-If.
.
Payment-Activity.
.
EXEC CICS DEFINE ACTIVITY('Payment')
TRANSID('SPAY')
EVENT('Payment-Complete')
RESP(data-area) RESP2(data-area) END-EXEC
.
EXEC CICS DEFINE TIMER('Payment-Due')
AFTER DAYS(7)
RESP(data-area) RESP2(data-area) END-EXEC
.
EXEC CICS GET CONTAINER(Invoice-Container)
ACTIVITY('Invoice') INTO(Invoice-Buffer)
RESP(data-area) RESP2(data-area) END-EXEC
.
EXEC CICS PUT CONTAINER(Invoice-Container)
ACTIVITY('Payment') FROM(Invoice-Buffer)
RESP(data-area) RESP2(data-area) END-EXEC
.
EXEC CICS RUN ACTIVITY('Payment')
ASYNCHRONOUS
RESP(data-area) RESP2(data-area) END-EXEC
.
Payment-Due-Response.
.
EXEC CICS DELETE TIMER('Payment-Due')
RESP(RC) RESP2(data-area) END-EXEC
.
Perform Reminder-Activity
Payment-Response.
.
EXEC CICS CHECK ACTIVITY('Payment') COMPSTATUS(status)
RESP(RC) RESP2(data-area) END-EXEC
.
If RC = DFHRESP(NORMAL)
If status = DFHVALUE(NORMAL)
EXEC CICS DELETE TIMER('Payment-Due')
RESP(RC) RESP2(data-area) END-EXEC
.
Perform End-process
Else
.
End-If
Else
.
End-If
.
Reminder-Activity.
.
EXEC CICS DEFINE ACTIVITY('Reminder')
TRANSID('PAYR')
EVENT('Remindr-Complete')
RESP(data-area) RESP2(data-area) END-EXEC
.
EXEC CICS DEFINE TIMER('Remindr-Expired')
AFTER DAYS(14)
RESP(data-area) RESP2(data-area) END-EXEC
.
EXEC CICS GET CONTAINER(Invoice-Container)
ACTIVITY('Invoice') INTO(Invoice-Buffer)
RESP(data-area) RESP2(data-area) END-EXEC
.
EXEC CICS PUT CONTAINER(Invoice-Container)
ACTIVITY('Reminder') FROM(Invoice-Buffer)
RESP(data-area) RESP2(data-area) END-EXEC
.
EXEC CICS RUN ACTIVITY('Reminder')
ASYNCHRONOUS
RESP(data-area) RESP2(data-area) END-EXEC
.
Reminder-Expired-Response.
.
EXEC CICS DELETE TIMER('Remindr-Expired')
RESP(RC) RESP2(data-area) END-EXEC
.
Perform Compensation
Reminder-Response.
.
EXEC CICS CHECK ACTIVITY('Reminder') COMPSTATUS(status)
RESP(RC) RESP2(data-area) END-EXEC
.
If RC = DFHRESP(NORMAL)
If status = DFHVALUE(NORMAL)
EXEC CICS DELETE TIMER('Remindr-Expired')
RESP(RC) RESP2(data-area) END-EXEC
.
Perform End-process
Else
.
End-If
Else
.
End-If
.
Compensation.
.
EXEC CICS DEFINE ACTIVITY('Payment-Compen')
TRANSID('PAYC')
PROGRAM('PEX001')
RESP(data-area) RESP2(data-area) END-EXEC
.
EXEC CICS PUT CONTAINER(Invoice-Container)
ACTIVITY('Payment-Compen') FROM(Invoice-Buffer)
RESP(data-area) RESP2(data-area) END-EXEC
.
EXEC CICS RUN ACTIVITY('Payment-Compen')
SYNCHRONOUS
RESP(data-area) RESP2(data-area) END-EXEC
.
EXEC CICS DEFINE ACTIVITY('Confirm-Compen')
TRANSID('CONC')
PROGRAM('REQ001')
RESP(data-area) RESP2(data-area) END-EXEC
.
EXEC CICS PUT CONTAINER(Deliver-Container)
ACTIVITY('Confirm-Compen') FROM(Delivery-Buffer)
RESP(data-area) RESP2(data-area) END-EXEC
.
EXEC CICS RUN ACTIVITY('Confirm-Compen')
SYNCHRONOUS
RESP(data-area) RESP2(data-area) END-EXEC
.
EXEC CICS DEFINE ACTIVITY('Delivery-Compen')
TRANSID('DELC')
PROGRAM('RTN001')
RESP(data-area) RESP2(data-area) END-EXEC
.
EXEC CICS PUT CONTAINER(Order-Container)
ACTIVITY('Delivery-Compen') FROM(Order-Buffer)
RESP(data-area) RESP2(data-area) END-EXEC
.
EXEC CICS RUN ACTIVITY('Delivery-Compen')
SYNCHRONOUS
RESP(data-area) RESP2(data-area) END-EXEC
.
EXEC CICS DEFINE ACTIVITY('Order-Compen')
TRANSID('ORDC')
PROGRAM('CAN001')
RESP(data-area) RESP2(data-area) END-EXEC
.
EXEC CICS PUT CONTAINER(Sale-Container)
ACTIVITY('Order-Compen') FROM(Process-Name)
RESP(data-area) RESP2(data-area) END-EXEC
.
EXEC CICS RUN ACTIVITY('Order-Compen')
SYNCHRONOUS
RESP(data-area) RESP2(data-area) END-EXEC
.
End-Process.
.
EXEC CICS RETURN ENDACTIVITY
RESP(data-area) RESP2(data-area) END-EXEC
End Program.
Note the following:
.
EXEC CICS DEFINE TIMER('Payment-Due')
AFTER DAYS(7)
RESP(data-area) RESP2(data-area) END-EXEC
.
The DEFINE TIMER command defines a timer which will expire in one week. Because the EVENT option is not specified, the event associated with the timer--the timer event--is given the same name as the timer itself (Payment-Due). Now, SAL002 will be reattached when either of the following happens:
As for the Payment activity, a timer is set for the Reminder activity. Now, SAL002 will be reattached when either of the following happens:
EXEC CICS DEFINE ACTIVITY('Payment-Compen')
TRANSID('PAYC')
PROGRAM('PEX001')
RESP(data-area) RESP2(data-area) END-EXEC
.
EXEC CICS PUT CONTAINER(Invoice-Container)
ACTIVITY('Payment-Compen') FROM(Invoice-Buffer)
RESP(data-area) RESP2(data-area) END-EXEC
.
EXEC CICS RUN ACTIVITY('Payment-Compen')
SYNCHRONOUS
RESP(data-area) RESP2(data-area) END-EXEC
Notice that the program used to execute the Payment-Compen compensation activity is different from that used for the Payment activity that is compensated. The PUT CONTAINER command provides the Payment-Compen activity with the same input data that was passed to the Payment activity.
Table 6 shows which activities are compensated, and the actions taken by the compensation activity in each case.
Completed child activity | Compensation activity | Actions taken by compensation activity |
---|---|---|
Payment | Payment-Compen | Cancels the outstanding payment request |
Confirm | Confirm-Compen | Sends a letter requesting return of goods |
Delivery | Delivery-Compen | Requests confirmation that the goods have been returned |
Order | Order-Compen | Cancels the original order request |