Using MODIFY or Maintain With SU

In this section:

This section discusses considerations that you should make when using MODIFY or Maintain to modify centrally controlled databases. This section covers:

In Maintain, you must issue the following command before running the application:

SET COMMIT = ON

Tip: Limit the number of records retrieved into a stack to reduce the chances of a conflict.


Top of page

x
Evaluating Conflicts: The FOCURRENT Field

When you submit a MODIFY or Maintain transaction in SU, FOCUS stores a code in a field called FOCURRENT. This field indicates whether or not there is a conflict with another transaction, as determined by the change/verify protocol (explained in Introduction). If the field value is 0, there is no conflict and the transaction is accepted. If the value is not 0, there is a conflict. In this case, the transaction is rejected and an error message is issued.

FOCUS treats a MODIFY or Maintain transaction that has been rejected because of a conflict as if it failed a validation test (the VALIDATE command). You can log these transactions using the LOG INVALID command described in the Maintaining Databases manual.

You can also design your MODIFY or Maintain requests to test FOCURRENT and branch according to its value. For example, a MODIFY or Maintain request can submit a transaction, test FOCURRENT, and, if FOCURRENT is not zero, resubmit the transaction. This technique is explained in Testing for Rejected Transactions.

The values assigned to FOCURRENT are:

0

Accepted.

1

Invalid, input will create duplicate.

2

Invalid, instance now deleted.

3

Invalid, instance has been changed.

The following table shows the possible values of FOCURRENT after different types of transactions. The rows list each type of transaction and the columns list the possible results. A hyphen (-) indicates that the transaction is rejected for reasons other than change/verify protocol.

User Desired Action

No Simultaneous Action

Instance Simultaneously:

Updated

Deleted

Included

UPDATE

0

3

2

-

DELETE

0

3

2

-

INCLUDE

0

-

-

1

In summary, the FOCURRENT field is not 0 if:

There is one additional case in which FOCURRENT is set to a non-zero value. If you issue a MATCH for a particular set of key values, the FOCUS Database Server saves the values of the retrieved segment instance. If you rematch on the same key values without intervening MATCH or NEXT commands against the database, the server compares the newly retrieved segment instance with the copy it saved on the first MATCH. If these two segment instances are the same, FOCURRENT is set to 0. If the segment instances differ, another user must have changed the segment instance since the original MATCH was performed. In this case, FOCURRENT is set to 1. This is the only case where FOCURRENT is set to a non-zero value on a MATCH command.

An example of this particular situation is shown in Validating CRTFORM Turnaround Fields (MODIFY Only).


Top of page

x
Testing for Rejected Transactions

By testing the FOCURRENT field, MODIFY or Maintain requests can process transactions even after they have been rejected because of conflicts. You design these requests using Case Logic. Case Logic is discussed in the Maintaining Databases manual.



Example: Resubmitting a Rejected Transaction

For example, assume a MODIFY or Maintain request resubmits a rejected transaction. There are two possible results:

In general, it is safe to branch to the same case again, as deadlocks cannot occur between two users. A transaction that resulted in a MATCH condition may, on resubmission, result in a NOMATCH condition, as the following request illustrates:

MODIFY FILE EMPLOYEE
PROMPT EMP_ID
GOTO NEWSAL
CASE NEWSAL
MATCH EMP_ID
   ON NOMATCH REJECT
   ON MATCH PROMPT CURR_SAL
   ON MATCH UPDATE CURR_SAL
   ON MATCH IF FOCURRENT NE 0 GOTO NEWSAL;
ENDCASE
DATA

The request prompts for an employee ID and branches to the NEWSAL case. If the ID is in the database, the NEWSAL case prompts for a salary, updates the salary on the source machine copy of the instance, and submits the transaction.

The procedure then tests the value of the field FOCURRENT. If FOCURRENT is 0, the transaction was accepted and the request prompts for the next ID. If FOCURRENT is not 0, meaning that the transaction was rejected, the request branches back to the top of the NEWSAL case and searches again for the employee ID in the database.

If the instance with the employee ID is still there, it prompts again for the salary and resubmits the transaction. But if the instance was deleted, the request returns a NOMATCH condition (ON NOMATCH REJECT) and prompts for the next transaction.


Top of page

x
Validating CRTFORM Turnaround Fields (MODIFY Only)

Always include FOCURRENT tests in MODIFY requests that validate CRTFORM turnaround fields. Otherwise, after a transaction is rejected as invalid, you may update a field without knowing that the field has been updated by someone else.

Turnaround fields are fields entered on the CRTFORM with a prefix (T.fieldname) used to display database values. They appear in CRTFORMs in MODIFY update requests (for example, T.SALARY). When you execute such a request, the present database value for the turnaround field (named SALARY, in this case) is displayed in the CRTFORM where you can change it or accept it as shown. (For more information on turnaround fields, see the Maintaining Databases manual.)

You can set up validation tests on turnaround fields, so that if you attempt to enter an invalid value for a field, the request can reject it and retrieve a fresh copy of the segment instance from the database, while redisplaying turnaround field values on the screen as you entered them (after you press the Enter key a second time).

Since the request redisplays the values from your first attempt, you do not know if another user updated these values after you began the transaction. Change/verify protocol will not reject the transaction, because the request retrieved a fresh copy of the instance after the first entries failed the validation tests (this copy contains the values updated by the other user, but these values are not displayed).

Therefore, your MODIFY request should test the FOCURRENT field after you retrieve data from the database with the MATCH command. If you previously matched on the same key values, and the instance currently in the database is not the same as your version of the instance, FOCURRENT contains the value 1.



Example: Testing FOCURRENT to Validate Turnaround Fields

The following example shows why the FOCURRENT test is needed and how it should be used.

This request updates employee salaries, allowing each employee a maximum salary of $50,000 yearly:

MODIFY FILE EMPLOYEE
CRTFORM
   "ENTER EMPLOYEE ID:   <EMP_ID"
MATCH EMP_ID
   ON NOMATCH REJECT
   ON MATCH CRTFORM LINE 2
      "ENTER SALARY: <T.CURR_SAL"
   ON MATCH VALIDATE
      SALTEST = IF CURR_SAL LE 50000 THEN 1 ELSE 0;
   ON INVALID TYPE
      "INVALID SALARY: PLEASE CORRECT VALUE"
   ON MATCH UPDATE CURR_SAL
   ON MATCH IF FOCURRENT NE 0 GOTO ERROR;
CASE ERROR
TYPE
   "FOCURRENT TEST FAILED"
   "ANOTHER USER HAS CHANGED THIS SEGMENT INSTANCE"
GOTO TOP
ENDCASE
DATA VIA FIDEL
END

The request prompts you for the employee ID number. After you enter the ID 071382660, FOCUS displays:

ENTER EMPLOYEE ID:           071382660
ENTER SALARY:                11000.00

Unknown to you, another user now updates the same instance, giving the employee a salary of $13,000. You change the salary to $15,000:

ENTER EMPLOYEE ID:           071382660
ENTER SALARY:                55000.00

But you see that you have made a mistake: you entered a salary of $55,000, which exceeds the $50,000 maximum. You receive a message that you entered an invalid salary value. You press Enter to redisplay the turnaround fields. FOCUS responds:

ENTER EMPLOYEE ID:           071382660
ENTER SALARY:                55000.00

Notice that the SALARY field still displays 55000.00, not the updated value 13,000, even though the request has just retrieved a fresh copy of the instance from the database. You change the salary to $15,000:

ENTER EMPLOYEE ID:           071382660
ENTER SALARY:                15000.00

When you press Enter, these values are entered into the database, canceling the update made by the other user (which may be correct).

To solve the problem, have the request test the FOCURRENT field when it retrieves copies of instances from the database. The previous MODIFY request could be written in the following manner (additions are in bold):

MODIFY FILE EMPLOYEE
CRTFORM
   "ENTER EMPLOYEE ID:   <EMP_ID"
MATCH EMP_ID
   ON NOMATCH REJECT
   ON MATCH IF FOCURRENT NE 0 GOTO ERROR; 
   ON MATCH CRTFORM LINE 2
      "ENTER SALARY: <T.CURR_SAL"
   ON MATCH VALIDATE
      SALTEST = IF CURR_SAL LE 50000 THEN 1 ELSE 0;
ON INVALID TYPE
      "INVALID SALARY: PLEASE CORRECT VALUE"
ON MATCH UPDATE CURR_SAL
ON MATCH IF FOCURRENT NE 0 GOTO ERROR;  
CASE ERROR
TYPE
   "FOCURRENT TEST FAILED"
   "ANOTHER USER HAS CHANGED THIS SEGMENT INSTANCE"
GOTO TOP
ENDCASE
DATA VIA FIDEL
END

Now when you enter the EMP_ID key, this MODIFY request first retrieves a copy of the instance with that EMP_ID value, then tests the FOCURRENT value. If FOCURRENT is not 0, the request branches back to the beginning and you must enter the EMP_ID number again. This will display the current turnaround field values in the database.

If you execute the previous request and enter an invalid salary, FOCUS clears the turnaround fields and notifies you of the failed validation test as before. But when you press Enter again, FOCUS tests the FOCURRENT field. If another user has changed the value of SALARY after you retrieved it, the reMATCH on EMP_ID returns a FOCURRENT value of 1. If FOCURRENT is not 0, CASE ERROR informs you that your transaction has failed the FOCURRENT test and requests that you re-enter the EMP_ID value. Only when you enter the EMP_ID value again does FOCUS retrieve a fresh copy of the instance, displaying the updated salary value:

ENTER EMPLOYEE ID:           071382660
ENTER SALARY:                13000.00

You can now decide to leave this updated value or change it.


Information Builders