Project: YugabyteDB (App Definition and Development / Database)
File: transaction-priority.md

title: Transaction priorities headerTitle: Transaction priorities linkTitle: Transaction priorities description: Transaction priorities in YugabyteDB. headcontent: Transaction priorities in YugabyteDB. menu: v2.18: name: Transaction priorities identifier: develop-quality-of-service-transaction-priorities parent: develop-quality-of-service weight: 235 type: docs <ul class="nav nav-tabs-alt nav-tabs-yb"> <li > <a href="../transaction-priority/" class="nav-link active"> <i class="icon-postgres" aria-hidden="true"></i> YSQL </a> </li> </ul> When using YugabyteDB with the concurrency control policy, higher priority transactions can abort lower priority transactions when conflicts occur. External applications may control the priority of individual transactions using the YSQL parameters `ybtransactionprioritylowerbound` and `ybtransactionpriorityupperbound`. A random number between the lower and upper bound is picked and used to compute a transaction priority for the transactions in that session as explained in . | Flag | Valid Range | Description | | : | :- | :- | | `ybtransactionprioritylowerbound` | Any value between 0 and 1, lower than the upper bound | Minimum transaction priority for transactions run in this session | | `ybtransactionpriorityupperbound` | Any value between 0 and 1, higher than the lower bound | Maximum transaction priority for transactions run in this session | To view the transaction priority of the active transaction in current session, use the `ybgetcurrenttransactionpriority` function. {{< note title="Note" >}} Currently, transaction priorities work in the following scenarios: Works with YSQL only, not supported for YCQL. Only applies for transactions using concurrency control policy. Only conflict resolution is prioritized, not resource consumption as a part. {{< /note >}} Create a and open two separate connections to it. {{< tip title="Tip - Use YugabyteDB Managed" >}} You can create a free cluster with , and open two cloud shell connections to it. These cloud shell connections open in two different browser tabs, which you can use to do the steps that follow. {{< /tip >}} Consider an example scenario of an maintaining a bank account. Create the accounts table and insert rows into it, as follows: ```sql create table account ( name text not null, type text not null, balance money not null default '0.00'::money, primary key (name, type) ); insert into account values ('kevin','saving', 500), ('kevin','checking', 500); ``` To set a transaction priority for concurrent transactions, perform a deposit and a withdrawal at the same time, and set a higher priority to deposit transactions. To simulate this, perform the two operations concurrently - a withdrawal in one session and a deposit in another session. The deposit transaction starts after the withdrawal has been initiated, but occurs before the withdrawal is completed from a separate session, as demonstrated in the following table: <table style="margin:0 5px;"> <tr> <td style="text-align:center;"><span style="font-size: 22px;">session #1 (withdrawal, low priority)</span></td> <td style="text-align:center; border-left:1px solid rgba(158,159,165,0.5);"><span style="font-size: 22px;">session #2 (deposit, high priority)</span></td> </tr> <tr> <td style="width:50%;"> Set the transaction priority to a lower range. <pre><code style="padding: 0 10px;"> set ybtransactionprioritylowerbound = 0.4; set ybtransactionpriorityupperbound= 0.6; </code></pre> </td> <td style="width:50%; border-left:1px solid rgba(158,159,165,0.5);"> Set the transaction priority to a higher range. <pre><code style="padding: 0 10px;"> set ybtransactionprioritylowerbound = 0.7; set ybtransactionpriorityupperbound= 0.9; </code></pre> </td> </tr> <tr> <td style="width:50%;"> Initiate the withdrawal of

<pre><code style="padding: 0 10px;"> begin transaction /lower priority transaction/; update account set balance = balance - 100::money where name='kevin' and type='checking'; </code></pre> The transaction has started, though not committed yet. <pre><code style="padding: 0 10px;"> select * from account; name | type | balance -+-+ kevin | checking | $400.00 kevin | saving | $500.00 (2 rows) </code></pre> </td> <td style="width:50%; border-left:1px solid rgba(158,159,165,0.5);"> </td> </tr> <tr> <td style="width:50%; border-right:1px solid rgba(158,159,165,0.5);"> </td> <td style="width:50%;"> Next, initiate the deposit of $200, which should have higher priority. <pre><code style="padding: 0 10px;"> begin transaction /high priority transaction/; update account set balance = balance + 200::money where name='kevin' and type='checking'; </code></pre> The transaction has started, though not committed yet. <pre><code style="padding: 0 10px;"> select * from account; name | type | balance -+-+ kevin | checking | $700.00 kevin | saving | $500.00 (2 rows) </code></pre> </td> </tr> <tr> <td style="width:50%;"> The withdrawal transaction will now abort because it conflicts with the higher priority deposit transaction. <pre><code style="padding: 0 10px;"> select * from account; ERROR: Operation failed. Try again: Unknown transaction, could be recently aborted: XXXX </code></pre> </td> <td style="width:50%; border-left:1px solid rgba(158,159,165,0.5);"> </td> </tr> <tr> <td style="width:50%; border-right:1px solid rgba(158,159,165,0.5);"> </td> <td style="width:50%;"> The deposit transaction can now commit. <pre><code style="padding: 0 10px;"> commit; COMMIT yugabyte=> select * from account; name | type | balance -+-+ kevin | checking | $700.00 kevin | saving | $500.00 (2 rows) </code></pre> </td> </tr> </table> The `ybgetcurrenttransactionpriority` function shows the transaction priority of the current transaction and the priority bucket the given priority belongs in. Transaction priority buckets are explained in detail in . The following example demonstrates the usage of `ybgetcurrenttransactionpriority`. From an active shell, create a table as follows: ```sql CREATE TABLE test_scan (i int, j int); ``` Start by setting the lower and upper bound values for your transaction. ```sql set ybtransactionprioritylowerbound = 0.4; set ybtransactionpriorityupperbound = 0.6; ``` In a transaction block, perform an insert and view the transaction priority as follows: ```sql BEGIN TRANSACTION ISOLATION LEVEL REPEATABLE READ; INSERT INTO test_scan (i, j) values (1, 1), (2, 2), (3, 3); SELECT ybgetcurrenttransactionpriority(); COMMIT; ``` ```output ybgetcurrenttransactionpriority 0.537144608 (Normal priority transaction) (1 row) ``` In the next transaction block, perform a `SELECT ... FOR UPDATE`, which results in a high priority transaction. ```sql set ybtransactionprioritylowerbound = 0.1; set ybtransactionprioritylowerbound = 0.4; BEGIN TRANSACTION ISOLATION LEVEL REPEATABLE READ; SELECT i, j FROM test_scan WHERE i = 1 FOR UPDATE; SELECT ybgetcurrenttransactionpriority(); COMMIT; ``` ```output ybgetcurrenttransactionpriority 0.212004009 (High priority transaction) (1 row) ``` The transaction priority is randomly chosen between the lower and upper bound. In the final transaction block, set `ybtransactionpriorityupperbound` and `ybtransactionprioritylowerbound` to be 1, and perform the same `SELECT ... FOR UPDATE` query as the previous one. This transaction type is of the highest priority. ```sql set ybtransactionpriorityupperbound = 1; set ybtransactionprioritylowerbound = 1; BEGIN TRANSACTION ISOLATION LEVEL REPEATABLE READ; SELECT i, j FROM test_scan WHERE i = 1 FOR UPDATE; SELECT ybgetcurrenttransactionpriority(); COMMIT; ``` ```output ybgetcurrenttransactionpriority Highest priority transaction (1 row) ``` For more information, see .