[
https://issues.apache.org/jira/browse/IGNITE-20560?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
]
Kirill Sizov updated IGNITE-20560:
-----------------------------------
Description:
If a cleanup operation crashes, it does not affect the transaction it was for
called since the transaction has been finished already.
However under certain circumstances we may *get the validation that prevents
commands from being executed on a finished transaction broken.*
The issue is that we have
{{PartitionReplicaListener.TxCleanupReadyFutureList.state}} that duplicates
local txState, and is updated in the cleanup command handler.
*Details*
{{PartitionReplicaListener.TxCleanupReadyFutureList.state}} is
* +updated+ in {{PartitionReplicaListener.processTxCleanupAction}} and
* +read+ in {{PartitionReplicaListener.appendTxCommand}}.
If the update has not been called because of a crash, the code in
{{appendTxCommand}}:
{code:java}
txCleanupReadyFutures.compute(txId, (id, txOps) -> {
if (txOps == null) {
txOps = new TxCleanupReadyFutureList();
}
if (isFinalState(txOps.state)) {
fut.completeExceptionally(
new
TransactionException(TX_FAILED_READ_WRITE_OPERATION_ERR, "Transaction is
already finished."));
} else {
txOps.futures.computeIfAbsent(cmdType, type -> new
ArrayList<>()).add(fut);
}
return txOps;
});{code}
will still read {{txOps.state}} as {{PENDING}} and will allow to execute this
command instead of throwing a {{TransactionException}}.
was:
If a cleanup operation crashes, it does not affect the transaction it was for
called since the transaction has been finished already.
However under certain circumstances we may *get the validation that prevents
commands from being executed on a finished transaction broken.*
The issue is that we have
{{PartitionReplicaListener.TxCleanupReadyFutureList.state}} that duplicates
local txState, and is updated in the cleanup command handler.
*Details*
{{PartitionReplicaListener.TxCleanupReadyFutureList.state}} is +updated+ in
{{PartitionReplicaListener.processTxCleanupAction}} and +read+ in
{{PartitionReplicaListener.appendTxCommand}}.
If the update has not been called because of a crash, the code in
{{appendTxCommand}}:
{code:java}
txCleanupReadyFutures.compute(txId, (id, txOps) -> {
if (txOps == null) {
txOps = new TxCleanupReadyFutureList();
}
if (isFinalState(txOps.state)) {
fut.completeExceptionally(
new
TransactionException(TX_FAILED_READ_WRITE_OPERATION_ERR, "Transaction is
already finished."));
} else {
txOps.futures.computeIfAbsent(cmdType, type -> new
ArrayList<>()).add(fut);
}
return txOps;
});{code}
will still read {{txOps.state}} as {{PENDING}} and will allow to execute this
command instead of throwing a {{TransactionException}}.
> It's possible to execute commands on a finished transaction under certain
> circumstances
> ---------------------------------------------------------------------------------------
>
> Key: IGNITE-20560
> URL: https://issues.apache.org/jira/browse/IGNITE-20560
> Project: Ignite
> Issue Type: Task
> Reporter: Kirill Sizov
> Priority: Major
> Labels: ignite-3
>
> If a cleanup operation crashes, it does not affect the transaction it was for
> called since the transaction has been finished already.
> However under certain circumstances we may *get the validation that prevents
> commands from being executed on a finished transaction broken.*
> The issue is that we have
> {{PartitionReplicaListener.TxCleanupReadyFutureList.state}} that duplicates
> local txState, and is updated in the cleanup command handler.
> *Details*
> {{PartitionReplicaListener.TxCleanupReadyFutureList.state}} is
> * +updated+ in {{PartitionReplicaListener.processTxCleanupAction}} and
> * +read+ in {{PartitionReplicaListener.appendTxCommand}}.
> If the update has not been called because of a crash, the code in
> {{appendTxCommand}}:
> {code:java}
> txCleanupReadyFutures.compute(txId, (id, txOps) -> {
> if (txOps == null) {
> txOps = new TxCleanupReadyFutureList();
> }
> if (isFinalState(txOps.state)) {
> fut.completeExceptionally(
> new
> TransactionException(TX_FAILED_READ_WRITE_OPERATION_ERR, "Transaction is
> already finished."));
> } else {
> txOps.futures.computeIfAbsent(cmdType, type -> new
> ArrayList<>()).add(fut);
> }
> return txOps;
> });{code}
> will still read {{txOps.state}} as {{PENDING}} and will allow to execute this
> command instead of throwing a {{TransactionException}}.
--
This message was sent by Atlassian Jira
(v8.20.10#820010)