Consultor Eletrônico



Kbase P147835: WRITE triggers fire out of order
Autor   Progress Software Corporation - Progress
Acesso   Público
Publicação   5/9/2010
Status: Verified

SYMPTOM(s):

WRITE triggers fire out of order

WRITE triggers do not fire in the same order as ASSIGN statements in the code.

Example using the Sports database:

Add the following code to the WRITE trigger for the Customer table:

DEFINE STREAM outf.
OUTPUT STREAM outf TO trigger.log APPEND.
PUT STREAM outf UNFORMATTED
'WRITE trigger for Cust-Num ' +
STRING(Customer.Cust-Num) +
' fired at time ' STRING(TIME)
SKIP.
OUTPUT STREAM outf CLOSE.
Run the following procedure:
DEFINE BUFFER buffer1 FOR Customer.
FIND FIRST buffer1 NO-LOCK.
/* Note that record is NOT released here */
FIND FIRST Customer NO-ERROR.
DO WHILE AVAILABLE(Customer):
Customer.Comments = 'New comment added at ' + STRING(TIME).
FIND NEXT Customer NO-ERROR.
END.
/* reference arbitrary record in Customer buffer */
FIND Customer where Customer.Cust-Num = 2 NO-LOCK.

trigger.log will look like this:

WRITE trigger for Cust-Num 2 fired at time 59071
WRITE trigger for Cust-Num 3 fired at time 59071
...
WRITE trigger for Cust-Num 84 fired at time 59072
WRITE trigger for Cust-Num 1 fired at time 59072


FACT(s) (Environment):

The same record is read into two different buffers.
The record in the first buffer is not released by reading another record into the buffer or by a RELEASE statement.
Records are then read and assigned new values in a sequential loop using a second buffer.
A record is referenced in the second buffer after the loop has completed.
All Supported Operating Systems
Progress/OpenEdge Product Family

CAUSE:

Enhancement Request# OE00196977

CAUSE:

A record that is not released stays in scope until the end of the nearest enclosing block with record scoping properties (that is, a FOR EACH block, a DO FOR block, or a REPEAT block). If no block within the procedure has record scoping properties, then the AVM scopes the record to the entire procedure, as in the example above. A write is not committed to the database until the record is released, so a WRITE trigger on the table also does not fire until that time. In this case, record 1 is released in the default Customer buffer, but is still active in buffer1. The WRITE trigger does not fire until the end of procedure, when the record is finally released from both buffers. In the meantime, other records are modified and released immediately, so their WRITE triggers fire in the expected sequence. The result is that the WRITE trigger for record 1 fires last instead of first.

An Enhancement Request was logged to provide a mechanism which will allow the WRITE triggers to fire in the exact same order as the ASSIGN statements are executed.

FIX:


This Enhancement has not been implemented in the product.

Use the RELEASE statement to explicitly release records when they are no longer needed. In the above example, add a RELEASE statement after the
FIND into buffer1:
FIND FIRST buffer1 NO-LOCK.
RELEASE buffer1.
With this change, trigger.log will look like this:
WRITE trigger for Cust-Num 1 fired at time 59071
WRITE trigger for Cust-Num 2 fired at time 59071
...
WRITE trigger for Cust-Num 83 fired at time 59072
WRITE trigger for Cust-Num 84 fired at time 59072