The accounts department performs additions, modifications, deletions, and inquiries by account number. Head office only needs to view and add new accounts. Customer requests will be restricted to inquiry by their account number only. These are the classic Create, Read, Update, and Delete (CRUD) functions of an application. Because the lock handling is specific to the CRUD activities, you decide to include this function in the program as well.
However, customer service performs ninety percent of its inquiries by name. This quite distinct feature does not fall into any of the normal CRUD activities. As a result you have decided to split the business logic into two distinct areas, the CRUD activities and the browse activities. However, underlying each process are the three key functions of the common error handling, creating a lock and freeing a lock:
Because error handling can be invoked from a variety (and possibly increasing number) of frontend presentation programs, the first thing the backend business logic programs must do is to ensure that the data passed seems reasonable. If it is not, the backend program needs to generate an error message to be returned to the frontend caller. Other errors that are encountered need to be handled.
We have discussed the need for locks and it is not surprising that this forms an important part of our code; this is required in order to ensure only one person can update the same account at a time. A check needs to be done to ensure that no other user currently owns the account record.
Because a lock must be obtained before any actual action is taken against an account, a function needs to exist to free it in case the user decides not to proceed with the original intention. A check needs to be done to ensure that the lock deletion is successful.
Figure 4-1 shows a summary of the key steps that are implemented in the business logic program. This is called NACT02 and you will find the complete code on the CD-ROM that accompanies this book.
The program (NACT02) adds a record to the file based on the data passed to it. It uses the three functions, handling errors, creating locks, and freeing locks, that we have just described. This procedure is common for the four functions of this part of our application (creating, reading, updating and deleting). However it must check that a lock is owned by the user requesting the add; this implies that a lock must be created. Likewise, at the end of the transaction the lock must be freed.
The process, therefore, consists of checking to see if a lock exists (maybe the record is in use by someone else). If not, it creates a lock, adds your record, confirms that it has been added sucessfully, and either returns an error message to the caller, or if it is successful, frees the lock and returns to caller.
This is slightly different from the process of creation, updating, and deletion in that there are actually two types of read required:
An inquiry only function
A read anticipating some sort of file update (thus requiring a lock)
If a lock was required, checking needs to be done to ensure that no other user currently “owns” the account. If all is well, then you attempt to read the record from the file.
This logic attempts to find all matches on the accounts file for the criteria specified. The initial search uses the name file, but the application must perform more specific filtering (based on first name). The four phases of this program, which is called NACT05, are similar to those of the CRUD program as shown in Figure 4-1. As with CRUD, the initial phase sets up the basic function of error handling as well as validation of the correct form of user input. Copybooks are used in all the sample programs to define interfaces so that everyone has the same layout.
The browse program (NACT05) scans the database for records matching the input value supplied by the end user. The position within the file to start scanning is passed using an EXEC CICS STARTBR command. If there are no matches, the program should return an appropriate message back to the user. Browsing itself does not involve any locks, but, of course, when using last names for a search there is always the possibility of duplicates. In step 3 of Figure 4-2 the command EXEC CICS READNEXT is invoked to continue the browse until the key last name does not match the input and the remainder of the program returns the results and displays them.
It is good practice to use an EXEC CICS ENDBR command to free any pointers to the file when you have finished scanning for matches. CICS will clean this up, if this is not done, at task termination.
This is one of the most complex areas of the system since it needs to handle a wide variety of scenarios. In order to allow for the future expansion of the system to include other functions, this should be designed to tolerate some scenarios that cannot happen with the original specification but which might occur in the future.
These scenarios include the ability for the program to be entered in a variety of ways, either under application or CICS control. The program needs to distinguish between these different possibilities. Much of the logic is specific to the CICS environment and is discussed later. However, in general, the error handler needs to:
Record information about the problem.
Back out any changes made in the current Unit Of Work (UOW)—see the glossary for a definition.
Send messages to the user, to a log, and possibly to the systems administrator responsible for CICS.
Terminate the task or return to the application program requesting these services.
Figure 4-3 is a high-level overview of the error handling program. We’ll discuss this in more details in the next chapter when we talk about actually programming the constituent pieces.