[
https://issues.apache.org/jira/browse/IGNITE-21521?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
]
Pavel Tupitsyn updated IGNITE-21521:
------------------------------------
Description:
Add the following test to *ItInternalTableTest* to reproduce:
{code:java}
@Test
public void upsertAllOrderTest() {
RecordView<Tuple> view = table.recordView();
InternalTable internalTable = ((TableViewInternal)
table).internalTable();
List<BinaryRowEx> rows = new ArrayList<>();
int count = 100;
int lastId = count - 1;
long id = 12345;
for (int i = 0; i < count; i++) {
rows.add(createKeyValueRow(id, i, "row-" + i));
}
internalTable.upsertAll(rows, null).join();
Tuple res = view.get(null, Tuple.create().set("key", id));
assertEquals(lastId, res.intValue("valInt"));
assertEquals("row-" + lastId, res.stringValue("valStr"));
}
{code}
As a user, I expect the last value for the given key to be applied. Instead, a
random value will be used.
This is caused by *PartitionReplicaListener* - when there is no row with
specified key, we generate a new random *RowId*:
{code:java}
RowId rowId0 = insert ? new RowId(partId(), UUID.randomUUID()) : rowId
{code}
Then this row id is stored in a hash set, which results in a random update
order. The same applies to the *DataStreamer*, which goes through
*InternalTableImpl.updateAll*.
was:
Add the following test to *ItInternalTableTest* to reproduce:
{code:java}
@Test
public void upsertAllOrderTest() {
RecordView<Tuple> view = table.recordView();
InternalTable internalTable = ((TableViewInternal)
table).internalTable();
List<BinaryRowEx> rows = new ArrayList<>();
int count = 100;
int lastId = count - 1;
long id = 12345;
for (int i = 0; i < count; i++) {
rows.add(createKeyValueRow(id, i, "row-" + i));
}
internalTable.upsertAll(rows, null).join();
Tuple res = view.get(null, Tuple.create().set("key", id));
assertEquals(lastId, res.intValue("valInt"));
assertEquals("row-" + lastId, res.stringValue("valStr"));
}
{code}
As a user, I expect the last value for the given key to be applied. Instead, a
random value will be used.
This is caused by *PartitionReplicaListener* - when there is no row with
specified key, we generate a new random *RowId*:
{code:java}
RowId rowId0 = insert ? new RowId(partId(), UUID.randomUUID()) : rowId
{code}
Then this row id is stored in a hash set, which results in a random update
order.
> Wrong update order in upsertAll and DataStreamer for a new key
> --------------------------------------------------------------
>
> Key: IGNITE-21521
> URL: https://issues.apache.org/jira/browse/IGNITE-21521
> Project: Ignite
> Issue Type: Bug
> Components: streaming
> Affects Versions: 3.0.0-beta1
> Reporter: Pavel Tupitsyn
> Assignee: Pavel Tupitsyn
> Priority: Major
> Labels: ignite-3
> Fix For: 3.0.0-beta2
>
>
> Add the following test to *ItInternalTableTest* to reproduce:
> {code:java}
> @Test
> public void upsertAllOrderTest() {
> RecordView<Tuple> view = table.recordView();
> InternalTable internalTable = ((TableViewInternal)
> table).internalTable();
> List<BinaryRowEx> rows = new ArrayList<>();
> int count = 100;
> int lastId = count - 1;
> long id = 12345;
> for (int i = 0; i < count; i++) {
> rows.add(createKeyValueRow(id, i, "row-" + i));
> }
> internalTable.upsertAll(rows, null).join();
> Tuple res = view.get(null, Tuple.create().set("key", id));
> assertEquals(lastId, res.intValue("valInt"));
> assertEquals("row-" + lastId, res.stringValue("valStr"));
> }
> {code}
> As a user, I expect the last value for the given key to be applied. Instead,
> a random value will be used.
> This is caused by *PartitionReplicaListener* - when there is no row with
> specified key, we generate a new random *RowId*:
> {code:java}
> RowId rowId0 = insert ? new RowId(partId(), UUID.randomUUID()) : rowId
> {code}
> Then this row id is stored in a hash set, which results in a random update
> order. The same applies to the *DataStreamer*, which goes through
> *InternalTableImpl.updateAll*.
--
This message was sent by Atlassian Jira
(v8.20.10#820010)