You are viewing a plain text version of this content. The canonical link for it is here.
Posted to issues@ignite.apache.org by "Alexey Scherbakov (Jira)" <ji...@apache.org> on 2026/05/14 12:05:00 UTC
[jira] [Updated] (IGNITE-28448) Prevent starvation on tx retries
[ https://issues.apache.org/jira/browse/IGNITE-28448?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ]
Alexey Scherbakov updated IGNITE-28448:
---------------------------------------
Description:
Currently _runInTransactionInternal_ restarts a transaction with a newer id.
This can cause starvation, because a transaction is counted as "new" (has low priority) and is a subject to be rejected on a conflict, according to deadlock prevention.
Instead, we need to preserve the start timestamp to keep it "old".
This can be implemented by adding restart counter to a transaction id and account it in comparator:
{code:java}
public static UUID transactionId(long beginTimestamp, int retryCnt, int nodeId, TxPriority priority) {
return new UUID(beginTimestamp, combine(nodeId, retryCnt, priority));
}
private static long combine(int nodeId, int retryCnt, TxPriority priority) {
int priorityAsInt = priority.ordinal();
// Shift the int 32 bits and combine with the boolean
return ((long) nodeId << 32) | ((long) retryCnt << 1) | priorityAsInt;
}
{code}
Benchmarks are required to measure the effect of this optimization under contention.
This is only affects implicit transaction restarts.
was:
Currently _runInTransactionInternal_ restarts a transaction with a newer id.
This can cause starvation, because a transaction is counted as "new" (has low priority) and is a subject to be rejected on a conflict, according to deadlock prevention.
Instead, we need to preserve the start timestamp to keep it "old".
This can be implemented by adding restart counter to a transaction id and account it in comparator:
{code:java}
public static UUID transactionId(long beginTimestamp, int retryCnt, int nodeId, TxPriority priority) {
return new UUID(beginTimestamp, combine(nodeId, retryCnt, priority));
}
private static long combine(int nodeId, int retryCnt, TxPriority priority) {
int priorityAsInt = priority.ordinal();
// Shift the int 32 bits and combine with the boolean
return ((long) nodeId << 32) | ((long) retryCnt << 1) | priorityAsInt;
}
{code}
Benchmarks are required to measure the effect of this optimization under contention.
> Prevent starvation on tx retries
> --------------------------------
>
> Key: IGNITE-28448
> URL: https://issues.apache.org/jira/browse/IGNITE-28448
> Project: Ignite
> Issue Type: Improvement
> Components: transactions ai3
> Reporter: Alexey Scherbakov
> Priority: Major
> Labels: ignite-3
>
> Currently _runInTransactionInternal_ restarts a transaction with a newer id.
> This can cause starvation, because a transaction is counted as "new" (has low priority) and is a subject to be rejected on a conflict, according to deadlock prevention.
> Instead, we need to preserve the start timestamp to keep it "old".
> This can be implemented by adding restart counter to a transaction id and account it in comparator:
> {code:java}
> public static UUID transactionId(long beginTimestamp, int retryCnt, int nodeId, TxPriority priority) {
> return new UUID(beginTimestamp, combine(nodeId, retryCnt, priority));
> }
> private static long combine(int nodeId, int retryCnt, TxPriority priority) {
> int priorityAsInt = priority.ordinal();
> // Shift the int 32 bits and combine with the boolean
> return ((long) nodeId << 32) | ((long) retryCnt << 1) | priorityAsInt;
> }
> {code}
> Benchmarks are required to measure the effect of this optimization under contention.
> This is only affects implicit transaction restarts.
--
This message was sent by Atlassian Jira
(v8.20.10#820010)