[
https://issues.apache.org/jira/browse/IGNITE-21572?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
]
Alexander Lapin updated IGNITE-21572:
-------------------------------------
Description:
h3. Motivation
Consider following scenario:
# Full (1PC) transaction tx1 starts on PrimaryReplica1 [leaseholder='X',
startTime='t1', endTime='t10']
# Within a given 1PC transaction 2-phase operation is evaluated over key1,
e.g. replace or increment (we do not have increment operation, however it's
easy to explain the problem with it, so let's assume that we have one).
# Within increment processing, processor acquires lock on key1, reads the
corresponding value and is about to write the new one.
# At this point, PrimaryReplica leaseholder='X' expires.
# Another transaction tx2 starts on new PrimaryReplica2 [leaseholder='Y',
startTime='t11', endTime='t21'].
# Within tx2 user also calls increment, thus also acquires lock, reads old
value and writes new one.
# tx2 finishes.
# tx1 successfully writes tx1.newValue overriding the value from tx2.
All in all, because tx2 didn't see tx1 locks because primary was changes
instead of (key1++)++ transactions will finish with (key1)++ which is of course
not valid.
h3. Definition of Done
* Buf is fixed.
h3. Implementation Notes
* As a fast fix we should use 1PC(full) transacions only in case of one-phase
operation, like put. All two-phase operations like replca, deleteExact, etc
should be evaluated within common 2PC transacion.
* Besides fast fix, we should consider cupporting invoke as a raft command
that will effectively convert read+write to an atomic operation.
> One phase transacion protocol is inconsistent in case of primary replica
> expirations
> ------------------------------------------------------------------------------------
>
> Key: IGNITE-21572
> URL: https://issues.apache.org/jira/browse/IGNITE-21572
> Project: Ignite
> Issue Type: Bug
> Reporter: Alexander Lapin
> Priority: Critical
> Labels: ignite-3
>
> h3. Motivation
> Consider following scenario:
> # Full (1PC) transaction tx1 starts on PrimaryReplica1 [leaseholder='X',
> startTime='t1', endTime='t10']
> # Within a given 1PC transaction 2-phase operation is evaluated over key1,
> e.g. replace or increment (we do not have increment operation, however it's
> easy to explain the problem with it, so let's assume that we have one).
> # Within increment processing, processor acquires lock on key1, reads the
> corresponding value and is about to write the new one.
> # At this point, PrimaryReplica leaseholder='X' expires.
> # Another transaction tx2 starts on new PrimaryReplica2 [leaseholder='Y',
> startTime='t11', endTime='t21'].
> # Within tx2 user also calls increment, thus also acquires lock, reads old
> value and writes new one.
> # tx2 finishes.
> # tx1 successfully writes tx1.newValue overriding the value from tx2.
> All in all, because tx2 didn't see tx1 locks because primary was changes
> instead of (key1++)++ transactions will finish with (key1)++ which is of
> course not valid.
> h3. Definition of Done
> * Buf is fixed.
> h3. Implementation Notes
> * As a fast fix we should use 1PC(full) transacions only in case of
> one-phase operation, like put. All two-phase operations like replca,
> deleteExact, etc should be evaluated within common 2PC transacion.
> * Besides fast fix, we should consider cupporting invoke as a raft command
> that will effectively convert read+write to an atomic operation.
--
This message was sent by Atlassian Jira
(v8.20.10#820010)