Transaction Boundaries

When desigining triggers, you need to understand how events and triggers interact with transaction boundaries.

The following topics are discussed:

Events

When designing Triggers, you must understand the ENOVIA Live Collaboration transaction model.

The discussion below is supplemental to the description in the of the MQL Guide chapter "The MQL Language".

Over time an object may transition from one state to another, as its properties are changed by events. The use of the term state here is more general than the States in an Policy. For example, changing the description of a business object is an event that changes the state of that business object, but the lifecycle State probably remains the same.

In the ENOVIA Studio Modeling Platform, each event is implicitly wrapped in a transaction boundary and the achievement of a new state is not complete until the transaction is committed (thus ensuring database consistency). Common Studio Modeling Platform functions are often actually a series of actions that rely on the proper execution of all of the previous actions. For example, checking access and logging history are actions that are implicitly wrapped in the transaction boundary of most Studio Modeling Platform operations. The design guarantees that objects are not updated without the history being logged.

ENOVIA Live Collaboration also allows transaction boundaries to be explicitly defined so that you can roll back all related actions if one of them fails. When transaction boundaries are implicit, the state of an object is considered changed as soon as an event transaction takes place. However, for an explicitly-defined transaction to be effective, each of its commands must be successful.

Triggers

When you add event triggers to the transaction model, the internal logic looks like this:

1) Event transaction is started 
    2) Normal processing of access checking occurs.* 
    3) If it exists, the Check Trigger is fired.
       4) If Check blocks, then transaction aborts.
          If not, the Override Trigger is fired if it exists.**
5) The Event transaction is then committed regardless of an override or normal 
activity.
6) Finally, if there is an Action Trigger, it is fired.

*Access is checked but the event is not stopped if no access. The RPE CHECKACCESSFLAG and ACCESSFLAG are set so the check and override events can determine current state and correct action.

**The lack of access will stop the event if the override does not override the event with some other operation.

If an event is part of a larger transaction, action programs may be defined with the Execute Deferred flag so that execution is deferred until after all transactions are committed. The transaction model looks like this:

1) Larger transaction is started with any number of commands before the Event with the 
trigger.
    2) Event transaction is started.
        3) Normal processing of access checking occurs.
        4) If it exists, the Check Trigger is fired.
        5) If Check blocks, then transaction aborts.
           If not, the Override Trigger is fired if it exists.
    6) The Event transaction is committed regardless of an override or normal       
activity.
    7) If the Event Trigger has a non-deferred Action Program, it is executed.
8) The larger transaction is committed if all activities and triggers succeed.
9) If the larger transaction successfully commits, and there is a deferred Action 
Program, it is now triggered. If the larger transaction aborts, deferred programs 
are not executed.

Deferred action programs will queue up if more than one is deferred within a transaction. This ensures that the order of execution remains the same as the Events which triggered them.