[ 
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{}}}.

 

*_Please note there are tests muted with this task._*

  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{}}}.
>  
> *_Please note there are tests muted with this task._*



--
This message was sent by Atlassian Jira
(v8.20.10#820010)

Reply via email to