The eXtremeDB MURSIW Transaction Manager

As explained in the Fundamental Concepts page, MURSIW is a traditional, lock-based transaction manager implemented as a simple queue. And it is important to note that when MURSIW is used the only possible Isolation level is MCO_SERIALIZABLE. The processing of transactions by MURSIW can be affected by setting Transaction Priorities and/or Transaction Scheduling Policy.

Upgrading transactions

As MURSIW uses a queue to process transactions, when a transaction upgrade API is called in the context of an MCO_UPDATE transaction, the upgrade is guaranteed to succeed. However, if there is already an MCO_UPDATE transaction in the queue or running, when a second MCO_UPDATE transaction is requested by the application, the transaction start API will block until the first MCO_UPDATE transaction has been completed (committed or rolled back).

To explain the logic within the MURSIW transaction manager implementation consider the following scenarios:

Scenario #1

If there is a single MCO_READ_ONLY transaction running, and the upgrade is requested, the transaction will be immediately promoted to MCO_READ_WRITE, even if there is another MCO_READ_WRITE transaction in the queue.

Scenario #2

If there are two (or more) MCO_READ_ONLY transactions running and one of them requests an upgrade (calls mco_trans_upgrade()), its status in the queue will be changed to UPDATE and it will be suspended until the other MCO_READ_ONLY transactions are committed or rolled back, then it will be promoted to MCO_READ_WRITE and continue executing (even if there are one or more MCO_READ_WRITE transactions in the queue).

Scenario #3

If there are two (or more) MCO_READ_ONLY transactions running and two (or more) of them request an upgrade (calls mco_trans_upgrade()), the first to request it will succeed and the other(s) will fail. The first will have its status in the queue changed to UPDATE and it will be suspended until the other MCO_READ_ONLY transactions are committed or rolled back, then it will be promoted to MCO_READ_WRITE and continue executing (even if there are one or more MCO_READ_WRITE transactions in the queue).

Scenario #4

There are no other transactions running or in the queue when an MCO_UPDATE transaction is started. The transaction enters the queue and is immediately scheduled with UPDATE status. Any other transaction (read or write) will be queued. When the upgrade API is called there may be other MCO_READ_ONLY or MCO_READ_WRITE transactions in the queue, but the MCO_UPDATE will be immediately promoted to MCO_READ_WRITE, even if the transactions that entered the queue after it are of a higher priority.

Scenario #5

There is already a transaction running or in the queue with status UPDATE when the transaction start API is called with transaction type MCO_UPDATE. In this case the transaction start API will block until the MCO_UPDATE transaction and all other transactions ahead of it in the queue have completed (committed or rolled back), then the transaction will execute with status UPDATE.

Scenario #6

There is already a transaction in the queue with status UPDATE when the upgrade API is called for a transaction of type MCO_READ_ONLY. In this case the upgrade API will return error code MCO_E_UPGRADE_FAIL.

So, the transaction types and concurrency with MURSIW can be summarized in the following table, where Y means that transactions of this type can run concurrently and N means that they run in serial:

  MCO_READ_ONLY MCO_READ_WRITE MCO_UPDATE*
MCO_READ_ONLY Y N Y
MCO_READ_WRITE N N N
MCO_UPDATE Y N N

* after the transaction start API is called and before the upgrade API is called; after the upgrade API the semantics are the same as MCO_READ_WRITE.

Note that a transaction may read, insert, update or delete a single object or many objects, even thousands, depending on the application’s needs. When processing blocks of objects in a single transaction it might happen that an object is deleted, but then before committing the transaction the same object is accessed again. If this occurs the read (get) or update (put) operation, or any other access such as locating the object in a cursor or generating XML on the object, will cause a fatal error code of MCO_ERR_OBJECT_HANDLE+N where N is a line number in the source code that identifies the exact point where the invalid handle was detected. In order to avoid this fatal error C applications can call the function mco_is_object_deleted() to determine if the object was deleted within the current transaction.