gtpd1m25Database Reference

Database Integrity

This section provides information about services that maintain TPFCS database integrity.

Database Access

There are no restrictions on which users can access the TPFCS database. Database access is denied only if the data store you requested does not exist. An application program informs the TPFCS database that you want to access the database. The TPFCS database assigns a token and saves any information required by the TPFCS database to communicate with you. Once you are known to the TPFCS database, you have access to all of the collections in the database. The TPFCS database has no service that restricts your access to only a subset of collections. If you are allowed to access the database, the TPFCS database then allows access to all the collections in the database.

Concurrency Controls

TPFCS provides three levels of concurrency control:

None (Nonlocking Cursor)

The first type of concurrency uses a nonlocking cursor to read elements in a collection without creating any type of interlock on the target collection. The same ECB or other ECBs can still issue requests to update the collection while the cursor is associated with the collection. Because the information can change underneath the cursor, the cursor may not iterate over all elements, it may iterate over some elements more than once, or it may no longer be valid. For this reason, a nonlocking cursor is considered a dirty-read cursor (see Dirty-Reader Protection). A subsequent request to lock the collection by the same ECB or another ECB will be successful and an exclusive lock will be placed on the collection by the new cursor. However, the nonlocking cursor will still be able to read elements in the collection. Nonlocking cursors are created by using the TO2_createCursor API. For more information, see TPF Application Programming.

Optimistic Concurrency (Update Sequence Counter)

To provide additional database integrity for those collections that allow element updating, an update sequence counter is stored in each element in a given collection and optimistic concurrency is enforced on the element during update processing. Optimistic concurrency allows you to read a collection and update it without exclusive access to the collection. When an element is to be updated, it must first be read from the collection with the returned sequence counter saved. The functions used to update elements in a collection require that the application provide the expected value for this counter. TPFCS increments the counter whenever a collection element is updated. If the collection is updated by some other user, your current update request will fail because the value passed by the application as input to the function does not match the update sequence counter embedded in the element. The collection must be retrieved again for a successful update to take place.

Pessimistic (Locking Cursor)

Pessimistic concurrency uses a locking cursor to create an exclusive lock on the collection. Write operations will only be allowed for the ECB creating the locking cursor. Any attempt by the same ECB to create another concurrent locking cursor on the collection will be rejected, and a request by another ECB to create a locking cursor will be forced to wait until the first ECB either deletes its locking cursor or exits. Locking cursors are created by using the TO2_createReadWriteCursor API. For more information, see TPF Application Programming.

Comparing Cursor Types

The following summarizes TPFCS operations involving the two different types of cursors:

A different ECB can also do all of the above.

When a locking cursor is used on a collection, the same ECB can:

The same ECB cannot create another locking cursor. A different ECB can do all of the above and it can also create another locking cursor, although the request will be deferred until the original locking cursor is deleted.

Dirty-Reader Protection

TPFCS provides dirty-reader protection by using the FILNC macro to file records in a sequence to make sure that an updated or new record is on the DASD surface before filing the record that points to the updated record. This is done to ensure that another user who is attempting to read the collection using a nonlocking cursor will be able to follow a whole chain. If the updates were filed in the wrong order, it might be possible for the reader to follow a chain with holes in it or the chain could point to records that were not even part of the collection; for example:

Record A contains a pointer to record B and now TPFCS has to insert record C between record A and B. If TPFCS filed record A with the new pointer to record C before filing record C, it would then be possible for a reader to read record A and then attempt to read record C before it had been filed. To prevent this, TPFCS dirty-reader protection will make sure that record C is filed first by using the FILNC macro, and then record A will be filed.

For more information about the FILNC macro, see TPF General Macros.

TPF Transaction Services

TPFCS uses TPF transaction services to create a commit scope on behalf of the caller for all update requests with the exception of cursor update requests. The application is responsible for commit scopes when using cursors. TPF transaction services will then either commit or roll back the change depending on the success of the request.

Note:
To determine which TPFCS functions use commit and rollback protocols, see the TPF C/C++ Language Support User's Guide.

The TPFCS database will also use commit and rollback protocols for maintaining its own structures in a consistent state. Therefore, an API that does not use commit and rollback on behalf of the caller may still activate the system commit and rollback protocols on behalf of the TPFCS database. Prime examples of this are most cursor functions that cause a collection to be changed.

TPF Transaction Services with Cursors

When using cursors, you should create a commit scope before creating a locking or nonlocking cursor on a collection. When using cursors, the TPFCS database maintains the state of the collection cached in storage. This can cause problems because there is no communication between the TPFCS database and the transaction processor of the system. Therefore, if you issue a commit or rollback request, the collection may not be committed or rolled back. You must delete the cursor before the commit or rollback request is issued. Otherwise, there is a possibility that some updates will not be committed or rolled back.

TPF Transaction Services with Dirty-Reader Protection

Using dirty-reader protection in a TPF commit scope can cause problems because of the way TPF transaction services supports FILNC macro requests in a loosely coupled system. TPF transaction services maintains a unique copy of every record filed using the FILNC macro. This is done so that TPF transaction services can honor the FILNC interface and make sure that the record has been filed before any following records that might have a pointer to the record. Therefore, every time a record is filed using the FILNC macro, TPF transaction services will add a copy of the record to the commit scope. For example, if the record is filed 500 times using the FILNC macro in the commit scope, there will be 500 copies of the record in the commit scope. This can cause TPF transaction services to exhaust its commit buffers. For more information about dirty-reader functions and programming considerations, see the TPF C/C++ Language Support User's Guide.

Shadowing

TPFCS provides an option on the TO2_create functions that allows you to specify that the collection is to be shadowed. When TPFCS shadows a collection, two copies of the collection are maintained: the prime and the shadow. TPFCS does this by allocating two DASD records for every record assigned to the collection. TPFCS will read one of the two records and will file all updates to both records. If the initial read fails, TPFCS automatically attempts to read the copy. When using normal TPF duplicate records for the collection, shadowing means that TPFCS is actually maintaining four copies of the data.

The shadow support can be set for a collection in one of two ways: The TO2_create type call that creates the collection can have the shadow option specified, or the specified data definition (DD) can have shadowing set on in it. If either the create call or the DD specifies shadowing, TPFCS activates shadowing for the created collection. Once a shadowing characteristic is created for a collection, it cannot be changed.

Note:
Shadowing is only supported for nontemporary persistent collections. The shadow option will result in an error if specified for a temporary collection.

To specify shadowing for a collection, enter the ZOODB DEFINE or ZOODB CHANGE command with the DD and SHADOW parameters specified. For more information about the ZOODB DEFINE or ZOODB CHANGE command, see TPF Operations.

Validation

TPFCS validation involves using the ZBROW command to perform a check of a subset of collection structures to ensure that they are built correctly. Errors are detected, isolated, and reported to the calling program, such as the ZBROW utility. A validation report will be returned to the user. This report will contain information about the types of errors found and the file addresses involved. The report will be sorted by error identifier. Each type of error will have a unique error identifier that indicates the severity of the error (generally, the lower the error identifier, the higher the severity). It is up to you to take additional actions to diagnose and repair the problems.

Reconstruction

Reconstruction involves correcting a subset of the fields in a control record of the collection and the chains that it anchors. Such reconstruction would be necessary if data becomes inaccessible as a result of data or control record corruption, logic errors, I/O errors, or a user error. The ZBROW RECONSTRUCT command is available to reconstruct these internal data and control structures from the beginning. It is up to you to make additional repairs by using the ZAFIL command.