While there are several “half way” schemes which will work occasionally, there is no way to ensure that an abend handler routine will always be called. It is not too hard to intercept application abends such as an 0C7 but system abends such as x37 are another matter entirely.
The only reliable ways to accomplish your objective are:
1) send the records to an MQ Series queue that is defined to “not roll back” messages in the event of an abend. Then have another program read those messages and write them to a QSAM file.
2) write the records to a database and issue a syncpoint after each write. Then at most the last record will be lost if an abend occurs in the process of the database write. It is fairly common to use a DB2 table (defined in a segmented tablespace) which is defined without an index for this purpose. When the program starts, it issues an unqualified DELETE to empty the table followed by a COMMIT. This DELETE takes only a small fraction of a second.
You gain a further advantage from either of these solutions. Should the batch program be running too long, such that there is a need to run multiple copies of the program in parallel; multiple instances of the program can be inserting records into either the queue or the table without contention and with full integrity.