As explained in the Fundamental Concepts page,
MURSIWis a traditional, lock-based transaction manager implemented as a simple queue. And it is important to note that whenMURSIWis used the only possible Isolation level isMCO_SERIALIZABLE. The processing of transactions byMURSIWcan be affected by setting Transaction Priorities and/or Transaction Scheduling Policy.Upgrading transactions
As
MURSIWuses a queue to process transactions, when a transaction upgrade API is called in the context of anMCO_UPDATEtransaction, the upgrade is guaranteed to succeed. However, if there is already anMCO_UPDATEtransaction in the queue or running, when a secondMCO_UPDATEtransaction is requested by the application, the transaction start API will block until the firstMCO_UPDATEtransaction has been completed (committed or rolled back).To explain the logic within the
MURSIWtransaction manager implementation consider the following scenarios:Scenario #1
If there is a single
MCO_READ_ONLYtransaction running, and the upgrade is requested, the transaction will be immediately promoted toMCO_READ_WRITE, even if there is anotherMCO_READ_WRITEtransaction in the queue.Scenario #2
If there are two (or more)
MCO_READ_ONLYtransactions running and one of them requests an upgrade (callsmco_trans_upgrade()), its status in the queue will be changed toUPDATEand it will be suspended until the otherMCO_READ_ONLYtransactions are committed or rolled back, then it will be promoted toMCO_READ_WRITEand continue executing (even if there are one or moreMCO_READ_WRITEtransactions in the queue).Scenario #3
If there are two (or more)
MCO_READ_ONLYtransactions 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 toUPDATEand it will be suspended until the otherMCO_READ_ONLYtransactions are committed or rolled back, then it will be promoted toMCO_READ_WRITEand continue executing (even if there are one or moreMCO_READ_WRITEtransactions in the queue).Scenario #4
There are no other transactions running or in the queue when an
MCO_UPDATEtransaction is started. The transaction enters the queue and is immediately scheduled withUPDATEstatus. Any other transaction (read or write) will be queued. When the upgrade API is called there may be otherMCO_READ_ONLYorMCO_READ_WRITEtransactions in the queue, but theMCO_UPDATEwill 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
UPDATEwhen the transaction start API is called with transaction typeMCO_UPDATE. In this case the transaction start API will block until theMCO_UPDATEtransaction 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
UPDATEwhen 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
MURSIWcan be summarized in the following table, whereYmeans that transactions of this type can run concurrently andNmeans 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+NwhereNis 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.