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 whenMURSIW
is used the only possible Isolation level isMCO_SERIALIZABLE
. The processing of transactions byMURSIW
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 anMCO_UPDATE
transaction, the upgrade is guaranteed to succeed. However, if there is already anMCO_UPDATE
transaction in the queue or running, when a secondMCO_UPDATE
transaction is requested by the application, the transaction start API will block until the firstMCO_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 toMCO_READ_WRITE
, even if there is anotherMCO_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 (callsmco_trans_upgrade()
), its status in the queue will be changed toUPDATE
and it will be suspended until the otherMCO_READ_ONLY
transactions are committed or rolled back, then it will be promoted toMCO_READ_WRITE
and continue executing (even if there are one or moreMCO_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 (callsmco_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 toUPDATE
and it will be suspended until the otherMCO_READ_ONLY
transactions are committed or rolled back, then it will be promoted toMCO_READ_WRITE
and continue executing (even if there are one or moreMCO_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 withUPDATE
status. Any other transaction (read or write) will be queued. When the upgrade API is called there may be otherMCO_READ_ONLY
orMCO_READ_WRITE
transactions in the queue, but theMCO_UPDATE
will be immediately promoted toMCO_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 typeMCO_UPDATE
. In this case the transaction start API will block until theMCO_UPDATE
transaction and all other transactions ahead of it in the queue have completed (committed or rolled back), then the transaction will execute with statusUPDATE
.Scenario #6
There is already a transaction in the queue with status
UPDATE
when the upgrade API is called for a transaction of typeMCO_READ_ONLY
. In this case the upgrade API will return error codeMCO_E_UPGRADE_FAIL
.So, the transaction types and concurrency with
MURSIW
can be summarized in the following table, whereY
means that transactions of this type can run concurrently andN
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
whereN
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 functionmco_is_object_deleted()
to determine if the object was deleted within the current transaction.