From 6bc7e9aaf9f9246bb5d8e91acf76c0bb00639f04 Mon Sep 17 00:00:00 2001 From: Pavel Tupitsyn Date: Thu, 2 Oct 2025 17:58:13 +0300 Subject: [PATCH 1/5] IGNITE-26495 .NET: Apache.Ignite.Tests.Transactions.TransactionsTests.TestReadOnlyTxSeesOldDataAfterUpdate(False) is flaky https://issues.apache.org/jira/browse/IGNITE-26495 --- .../Apache.Ignite.Tests/Transactions/TransactionsTests.cs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/modules/platforms/dotnet/Apache.Ignite.Tests/Transactions/TransactionsTests.cs b/modules/platforms/dotnet/Apache.Ignite.Tests/Transactions/TransactionsTests.cs index 188bb5d8ef50..14602bc3b1e2 100644 --- a/modules/platforms/dotnet/Apache.Ignite.Tests/Transactions/TransactionsTests.cs +++ b/modules/platforms/dotnet/Apache.Ignite.Tests/Transactions/TransactionsTests.cs @@ -227,6 +227,8 @@ public async Task TestReadOnlyTxSeesOldDataAfterUpdate([Values(true, false)] boo await PocoView.UpsertAsync(transaction: null, new Poco { Key = key, Val = "22" }); // Old read-only tx sees old data. + // TODO: This fails if (somehow??) the upserts are on different channels - see the log in the ticket. + // Imitate this to reproduce. Assert.AreEqual("11", (await PocoView.GetAsync(roTx, keyPoco)).Value.Val); // New tx sees new data From 3cb7b3619c06015b64de075c27c5bd9e46ec5f1f Mon Sep 17 00:00:00 2001 From: Pavel Tupitsyn Date: Mon, 6 Oct 2025 14:41:26 +0300 Subject: [PATCH 2/5] wip --- .../Apache.Ignite.Tests/Transactions/TransactionsTests.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/modules/platforms/dotnet/Apache.Ignite.Tests/Transactions/TransactionsTests.cs b/modules/platforms/dotnet/Apache.Ignite.Tests/Transactions/TransactionsTests.cs index 14602bc3b1e2..cf49cf6e923d 100644 --- a/modules/platforms/dotnet/Apache.Ignite.Tests/Transactions/TransactionsTests.cs +++ b/modules/platforms/dotnet/Apache.Ignite.Tests/Transactions/TransactionsTests.cs @@ -211,8 +211,10 @@ public async Task TestTransactionFromAnotherClientThrows() [Test] public async Task TestReadOnlyTxSeesOldDataAfterUpdate([Values(true, false)] bool readBeforeUpdate) { - var key = Random.Shared.NextInt64(1000, long.MaxValue); + // TODO: Upserts go to different channels for this key - why? + var key = 2373697073179453717; var keyPoco = new Poco { Key = key }; + Console.WriteLine(key); await PocoView.UpsertAsync(null, new Poco { Key = key, Val = "11" }); @@ -227,8 +229,6 @@ public async Task TestReadOnlyTxSeesOldDataAfterUpdate([Values(true, false)] boo await PocoView.UpsertAsync(transaction: null, new Poco { Key = key, Val = "22" }); // Old read-only tx sees old data. - // TODO: This fails if (somehow??) the upserts are on different channels - see the log in the ticket. - // Imitate this to reproduce. Assert.AreEqual("11", (await PocoView.GetAsync(roTx, keyPoco)).Value.Val); // New tx sees new data From 7a28f141514c0aee47f6249ce5c984dbaa2b0c08 Mon Sep 17 00:00:00 2001 From: Pavel Tupitsyn Date: Mon, 6 Oct 2025 14:52:33 +0300 Subject: [PATCH 3/5] Add workaround --- .../Transactions/TransactionsTests.cs | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/modules/platforms/dotnet/Apache.Ignite.Tests/Transactions/TransactionsTests.cs b/modules/platforms/dotnet/Apache.Ignite.Tests/Transactions/TransactionsTests.cs index cf49cf6e923d..603df4e518f0 100644 --- a/modules/platforms/dotnet/Apache.Ignite.Tests/Transactions/TransactionsTests.cs +++ b/modules/platforms/dotnet/Apache.Ignite.Tests/Transactions/TransactionsTests.cs @@ -211,10 +211,14 @@ public async Task TestTransactionFromAnotherClientThrows() [Test] public async Task TestReadOnlyTxSeesOldDataAfterUpdate([Values(true, false)] bool readBeforeUpdate) { - // TODO: Upserts go to different channels for this key - why? - var key = 2373697073179453717; + // Use single-node connection to work around TODO ticket. + var cfg = GetConfig(); + cfg.Endpoints.Clear(); + cfg.Endpoints.Add($"127.0.0.1:{ServerPort}"); + + using var client = await IgniteClient.StartAsync(GetConfig()); + var key = Random.Shared.NextInt64(1000, long.MaxValue); var keyPoco = new Poco { Key = key }; - Console.WriteLine(key); await PocoView.UpsertAsync(null, new Poco { Key = key, Val = "11" }); From 82079d61290b9c51f7c25be66cb65111c0e216d2 Mon Sep 17 00:00:00 2001 From: Pavel Tupitsyn Date: Mon, 6 Oct 2025 14:55:51 +0300 Subject: [PATCH 4/5] Add workaround --- .../Transactions/TransactionsTests.cs | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/modules/platforms/dotnet/Apache.Ignite.Tests/Transactions/TransactionsTests.cs b/modules/platforms/dotnet/Apache.Ignite.Tests/Transactions/TransactionsTests.cs index 603df4e518f0..de899da5aad7 100644 --- a/modules/platforms/dotnet/Apache.Ignite.Tests/Transactions/TransactionsTests.cs +++ b/modules/platforms/dotnet/Apache.Ignite.Tests/Transactions/TransactionsTests.cs @@ -216,28 +216,30 @@ public async Task TestReadOnlyTxSeesOldDataAfterUpdate([Values(true, false)] boo cfg.Endpoints.Clear(); cfg.Endpoints.Add($"127.0.0.1:{ServerPort}"); - using var client = await IgniteClient.StartAsync(GetConfig()); + using var client = await IgniteClient.StartAsync(cfg); + var recordView = (await client.Tables.GetTableAsync(TableName))!.GetRecordView(); + var key = Random.Shared.NextInt64(1000, long.MaxValue); var keyPoco = new Poco { Key = key }; - await PocoView.UpsertAsync(null, new Poco { Key = key, Val = "11" }); + await recordView.UpsertAsync(null, new Poco { Key = key, Val = "11" }); - await using var roTx = await Client.Transactions.BeginAsync(new TransactionOptions { ReadOnly = true }); + await using var roTx = await client.Transactions.BeginAsync(new TransactionOptions { ReadOnly = true }); if (readBeforeUpdate) { - Assert.AreEqual("11", (await PocoView.GetAsync(roTx, keyPoco)).Value.Val); + Assert.AreEqual("11", (await recordView.GetAsync(roTx, keyPoco)).Value.Val); } // Update data in a different (implicit) tx. - await PocoView.UpsertAsync(transaction: null, new Poco { Key = key, Val = "22" }); + await recordView.UpsertAsync(transaction: null, new Poco { Key = key, Val = "22" }); // Old read-only tx sees old data. - Assert.AreEqual("11", (await PocoView.GetAsync(roTx, keyPoco)).Value.Val); + Assert.AreEqual("11", (await recordView.GetAsync(roTx, keyPoco)).Value.Val); // New tx sees new data - await using var tx3 = await Client.Transactions.BeginAsync(new TransactionOptions { ReadOnly = true }); - Assert.AreEqual("22", (await PocoView.GetAsync(tx3, keyPoco)).Value.Val); + await using var tx3 = await client.Transactions.BeginAsync(new TransactionOptions { ReadOnly = true }); + Assert.AreEqual("22", (await recordView.GetAsync(tx3, keyPoco)).Value.Val); } [Test] From 3a25c997536990a2637fe608dcec3bbeae20add3 Mon Sep 17 00:00:00 2001 From: Pavel Tupitsyn Date: Mon, 6 Oct 2025 16:50:59 +0300 Subject: [PATCH 5/5] Link ticket --- .../Apache.Ignite.Tests/Transactions/TransactionsTests.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/modules/platforms/dotnet/Apache.Ignite.Tests/Transactions/TransactionsTests.cs b/modules/platforms/dotnet/Apache.Ignite.Tests/Transactions/TransactionsTests.cs index de899da5aad7..e7433c08d3b2 100644 --- a/modules/platforms/dotnet/Apache.Ignite.Tests/Transactions/TransactionsTests.cs +++ b/modules/platforms/dotnet/Apache.Ignite.Tests/Transactions/TransactionsTests.cs @@ -211,7 +211,8 @@ public async Task TestTransactionFromAnotherClientThrows() [Test] public async Task TestReadOnlyTxSeesOldDataAfterUpdate([Values(true, false)] bool readBeforeUpdate) { - // Use single-node connection to work around TODO ticket. + // TODO IGNITE-26619 Implicit client ro tx does not include observableTimestamp - remove workaround below. + // Use single-node connection to work around causality issues due to round-robin in GetNextSocketWithoutReconnect. var cfg = GetConfig(); cfg.Endpoints.Clear(); cfg.Endpoints.Add($"127.0.0.1:{ServerPort}");