technical: Do Your CICS/VSAM Datasets Have Full Read Integrity?
Your CICS/VSAM datasets are unlikely to have full read integrity: applications will see record updates (or deletes) before a CICS syncpoint.
In our partner article, we found that VSAM record updates from CICS are immediately written to disk: no flushing of buffers needed. But more interestingly, this means that updates are written to disk BEFORE a CICS syncpoint occurs. Let's look at what this means for read integrity.
Suppose we have a CICS transaction (TXN1) that:
- Updates Record 1
- EXEC CICS SYNCPOINT
- Updates Record 2
- Ends (with an implicit syncpoint)
If TXN1 abended just before step 3, CICS will automatically backout the update of Record 1 as part of its handling of transaction abends. But updates are written to disk before syncpoints. So, when CICS backs out this update, it will go to DFHLOG, get a ‘before image' of Record 1, and write this to our VSAM dataset.
The same if the CICS region fails just before step 3. When CICS restarts, it does an emergency restart, and backs out uncommitted TXN1 changes. It will go to DFHLOG, get the before image of Record 1, and then write this to the VSAM dataset.
Why does this matter?
If a batch job reads our VSAM dataset just before Step 3, it will see the update to Record 1, even though it is about to be ‘backed out.' Similarly, if it reads the VSAM data while the CICS region is down after a crash (and about to be restarted). Or in other words, it will see an uncommitted update.
There's no read integrity. Let's look a bit closer at this.
If a batch job backs up a VSAM dataset, it may include uncommitted updates. So, if the backup is restored, there's a chance of a data integrity failure: an update that should be backed out remaining. This may sound trivial: do we really care about one update? In many cases, the answer is probably "no". But in some, the answer may be "yes."
Features like concurrent copy and backout while open (BWO) may seem to be a solution: they do add some read integrity. However, they don't necessarily avoid the 'uncommitted read' problem we're talking about.
The popular solution is to use some kind of forward recovery solution for backups: think IBM CICSVR or BMC RUV. These will restore from a fuzzy backup, and then forward recover from logs to a certain 'recovery point'. This effectively solves our problem.
Interestingly, other IBM products fact the same problem. For example, IBM MQ page sets are VSAM datasets. If these are backed up while they are in use, they must be restored together with the MQ logs to perform necessary updates for in-flight units of work.
Same with CICS
The same problem occurs within CICS. If we have a second transaction (TXN2) in the same CICS region that reads our VSAM dataset just before step 3 of TXN1, it will see the uncommitted update. No read integrity in CICS.
CICS assumes that CICS programs that need full read integrity (i.e. only see committed updates) will implement their own serialization (think EXEC CICS ENQ). Though you may not find this spelled out in the CICS documentation.
If you've defined your file to use Non-Shared Resources (NSR), the problem may be worse. With LSR, a program reading a record will wait if another program is updating a record in the control interval: no chance of reading ‘half updated' records. With NSR, this may not be the case.
The Solution: RLS Consistent Read
This has been a long-standing problem, that IBM have only (relatively recently) resolved with VSAM RLS. With VSAM RLS, you can specify the required read integrity options:
- CR – consistent read. If one task is updating a record, others will wait for this update to complete before they can read it.
- CRE – see REPEATABLE in the CICS definition.
- NRI – no read integrity. If one task is updating a record, others can read it.
This can be done in the RLSREAD parameter of the VSAM ACB block when using the VSAM macros. It can also be done from batch:
// EXEC PGM=BATCHP1
//DD1 DD DSN=MY.VSAM.DSET,RLS=NRI,DISP=SHR
The RLS option on the DD card is ignored by CICS: RLS options must be specified in the CICS FCT READINTEG parameter:
- UNCOMMITTED – if the record.
- CONSISTENT – if the record is being updated by one task, other tasks wait until the update is complete. This is at the next syncpoint if the file is recoverable: otherwise when the update is completed.
- REPEATABLE– as for consistent. However, the reading task will lock the record until the next syncpoint. So, if a task reads a record, it cannot be updated until that task ends the unit of work.
So with consistent or repeatable read integrity for recoverable files, a task reading a record must wait for the CICS unit of work of an updating application to finish. Read integrity options can also be specified on the EXEC CICS statements. For example:
EXEC CICS READ(FILE1) CONSISTENT INTO(AREA1) RIDFIELD(KEY1)
This sounds great, however this integrity comes at a cost: performance. VSAM must do a lot more work (and more locking) to achieve this enhanced read integrity.
The chances are that your CICS transactions don't have full read integrity today. And non-CICS processes accessing open CICS VSAM datasets won't either. This can now be resolved using integrity options available with VSAM RLS. However, these come at a performance cost.