About Transactions

A transactional event is an application event or set of event handlers in which all must complete successfully before any data is committed in the system. If any handler fails, then the system rolls back or reverts all data to its initial state.

If the transactional event contains any adjourning event actions, the system modifies this behavior somewhat: Any actions taken up to the first adjournment, between each resumption of an adjournment and the beginning of the next adjournment, and after the last resumption, are each committed separately.

The system treats any asynchronous event handlers as if they belong to an asynchronously generated non-transactional event. In other words, because they are outside the synchronous flow, these event handlers are not treated as part of the transaction.

Transactions with synchronous events

An event generated synchronously without the Transactional check box selected on the Event Handlers form either:

  • Runs in the current transaction state of the firing thread, if no lower-level transactioning is specified
  • Handles transactions at the event handler or event action level, as explained in these points:
    • In the middle tier, any execution methods for database-related event actions must enlist in an existing transaction or create a new one.

      To include the entire event in a single transaction, call the FireApplicationEvent method from a hand-coded IDO method that is marked Transactional in the IDO metadata. In this case, the execution methods for the database-related event action enlist in the transaction created by the IDO Runtime for that transactional IDO method.

      When the FireApplicationEvent method is called from a hand-coded IDO method that is not marked Transactional and whose caller is not in a transaction state, each event action execution method creates a new transaction, which is rolled back in case of failure, except when the containing event handler is marked Transactional. Changes to event system state data are performed in a separate connection, except in suspend-validating mode, so they survive any rollback of the encompassing or wrapping transactions.

    • The client is not permitted to control transactions that span form event handler calls. Client- tier event-firing requests are passed directly on to the MGCore.Events.FireEvent IDO method.

A failure of a synchronous event returns an error condition to the firing thread. For framework events, this causes the entire current transaction to be rolled back. For application events, whatever generated the event, through .NET method or VB.NET script, is responsible for trapping the error condition, accomplishing a rollback of the current transaction, and throwing execution to an appropriate recovery point in or out of that code.

Transactional event handlers

An event handler marked Transactional is wrapped in a new transaction when executed from the middle tier, if no encompassing transaction is active at the trigger point of the outermost enclosing event.

This event handler cannot contain any adjourning event action types, such as Prompt, Wait, Discover File, and Sleep, but can be marked Asynchronous itself. If this event handler ends in a failure, the wrapping transaction is rolled back, assuming it was created.

Non-transactional event handlers

An application event that is generated asynchronously without the Transactional setting does not run in a transaction state. Event handlers that are not marked Transactional, for a synchronous event generated from a middle-tier non-transactional custom IDO method, are handled this way:

  • An application event can be generated asynchronously with a Transactional setting that indicates that a new transaction has begun and the entire database-related effects of its synchronous event handlers are committed if they all succeed or rolled back if any fail.
  • Any asynchronous event handlers are treated as if they belong to an asynchronously generated non-transactional event.