# Transaction Priorities and Scheduling

> With `MURSIW`, eXtremeDB supports transaction priorities; i.e. it is possible to assign a priority value to each transaction at runtime. At the time a transaction is registered with the runtime, the transaction scheduler checks the priority value and shifts the transaction forward or backwards in the transaction queue accordingly. With the `MURSIW` transaction manager, applications normally execute as foreground transactions, however by using the transaction priority mechanism, an application can also “boost” the execution of a transaction to high-priority at runtime if necessary. The eXtremeDB transaction priorities are defined as follows:

> MCO_TRANS_IDLE | Least important transactions
> MCO_TRANS_BACKGROUND | Less important then foreground but more important then idle
> MCO_TRANS_FOREGROUND | Normal priority transactions
> MCO_TRANS_HIGH | More important then foreground but less important then ISR
> MCO_TRANS_ISR | Very Important Transactions

> ## MVCC Transaction Priocessing

> Transaction priorities with `MVCC` have a slightly different meaning. Transactions with priority above "normal" (`MCO_TRANS_FOREGROUND`) lock the entire index – reducing parallel access to tree and hash structures to read-only access. By doing so, the transaction avoids locking index pages during cursor movements, which can improve performance when there’s a need to iterate over many objects. The lock is released when a cursor reaches the end of the result set, or by calling the cursor `close` method. The implication of reducing parallel access to tree and hash structures (indexes) to read-only is that a parallel transaction updating objects of the same class when the class in question does not have `oid` or `autoid`, will block when it calls the transaction commit function, until the higher priority task releases the lock. For classes with `oid` or `autoid`, the `oid` or `autoid` index is updated as soon as the class `new` method is invoked, so the parallel task will be blocked on this function until the higher priority task releases the lock. The potential for parallel tasks to be blocked needs to be weighed against the performance gain of avoiding setting and releasing a short term lock during each cursor movement (e.g. the cursor `next` method).

> When adjusting Transaction Priority be aware of the “Priority Inversion Problem” described at http://en.wikipedia.org/wiki/Priority_inversion .

> ## MURSIW Transaction Scheduling Policies

> The `MURSIW` transaction manager algorithm places all incoming transactions into the queue according to the Transaction Priority. When a new incoming transaction attempts to gain access to the database runtime, the `MURSIW` manager makes sure that

> - there is no conflict with an already active transaction
> - there is no higher or equal priority transaction waiting in the queue

> If the incoming transaction is a read-write transaction (`MCO_READ_WRITE`), the database runtime does not check on the higher priority transactions. The rationale behind this is that even if there were any higher priority transactions at the moment, it would indicate that they were waiting on some other transaction that would prevent the incoming one to get exclusive ("read-write") access to the database. Once the transaction is finalized (committed or rolled back), the `MURSIW` algorithm picks the next transaction from the queue. In order to avoid a scenario in which active "read-only" transactions block access to a higher priority "read-write" transaction, and to ensure the FIFO scheduling policy, the `MURSIW` transaction manager does not allow an incoming read-only transaction with a priority lower than a queued read-write transaction priority to get scheduled right-away.

> The default scheduling policy of transaction priorities can be controlled by the application using the following flags which determine the policy for transactions with the same priority:

> MCO_SCHED_FIFO | The default First-In-First-Out scheduling
> MCO_SCHED_READER_FAVOR | Prioritize read-only transactions by placing them ahead of the same priority read-write transactions into the queue
> MCO_SCHED_WRITER_FAVOR | Prioritize read-write transactions