Programming guidelines
The number, type, and sequence of the IMS™ requests your program issues affects the efficiency of your program. A program that is poorly designed can still run if it is coded correctly. IMS will not find design errors for you. The suggestions that follow will help you develop the most efficient design possible for your application program.
When you have a general sequence of calls mapped out for your program, look over the guidelines on sequence to see if you can improve it. An efficient sequence of requests results in efficient internal IMS processing. As you write your program, keep in mind the guidelines explained in this topic. The following list offers programming guidelines that will help you write efficient and error-free programs.
- Use the most simple call. Qualify your requests to narrow the search for IMS.
- Use the request or sequence of requests that will give IMS the shortest path to the segment you want.
- Use as few requests as possible. Each DL/I call your program issues
uses system time and resources. You may be able to eliminate unnecessary
calls by:
- Using path requests when you are replacing, retrieving, or inserting more than one segment in the same path. If you are using more than one request to do this, you are issuing unnecessary requests.
- Changing the sequence so that your program saves the segment in a separate I/O area, and then gets it from that I/O area the subsequent times it needs the segment. If your program retrieves the same segment more than once during program execution, you are issuing unnecessary requests.
- Anticipating and eliminating needless and nonproductive requests, such as requests that result in GB, GE, and II status codes. For example, if you are issuing GN calls for a particular segment type, and you know how many occurrences of that segment type exist, do not issue the GN that results in a GE status code. Keep track of the number of occurrences your program retrieves, and then continue with other processing when you know you have retrieved all the occurrences of that segment type.
- Issuing an insert request with a qualification for each parent, rather than issuing Get requests for the parents to make sure that they exist. If IMS returns a GE status code, at least one of the parents does not exist. When you are inserting segments, you cannot insert dependent segments unless the parent segments exist.
- Commit your updates regularly. IMS limits full-function databases so that only 300 databases at a time can have uncommitted updates. Logically related databases, secondary indexes, and HALDB partitions are counted towards this limit. The number of partitions in HALDB databases is the most common reason for approaching the 300 database limit for uncommitted updates. If the PROCOPT values allow a BMP application to insert, replace, or delete segments in the databases, ensure that the BMP application does not update a combined total of more than 300 databases and HALDB partitions without committing the changes.
- Keep the main section of the program logic together. For example, branch to conditional routines, such as error and print routines in other parts of the program, instead of branching around them to continue normal processing.
- Use call sequences that make good use of the physical placement of the data. Access segments in hierarchic sequence as often as possible, and avoid moving backward in the hierarchy.
- Process database records in order of the key field of the root segments. (For HDAM and PHDAM databases, this order depends on the randomizing routine that is used. Check with your DBA for this information.)
- Avoid constructing the logic of the program and the structure of commands or calls in a way that depends heavily on the database structure. Depending on the current structure of the hierarchy reduces the program's flexibility.
- Minimize the number of segments your program locks. You may need
to take checkpoints to release the locks on updated segments and the
lock on the current database record for each PCB your program uses.
Each PCB used by your program has the current database record locked
at share or update level. If this lock is no longer required, issuing
the GU call, qualified at the root level with a greater-than
operator for a key of X'FF' (high values), releases the current
lock without acquiring a new lock.
Do not use the minimization technique if you use a randomizer that puts high values at the end of the database and you use secondary indexes. If there is another root beyond the supposed high value key, IMS returns a GE to allow the application to determine the next step. A secondary index might not work because the hierarchical structure is inverted, and although the key is past the last root in the index, it might not be past the last root in the database.
Using PCBs with a processing option of get (G) results in locks for the PCB at share level. This allows other programs that use the get processing option to concurrently access the same database record. Using a PCB with a processing option that allows updates (I, R, or D) results in locks for the PCB at update level. This does not allow any other program to concurrently access the same database record.