You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ignite.apache.org by rp...@apache.org on 2025/05/15 17:48:35 UTC
(ignite-3) branch main updated: IGNITE-25385 Make TransactionExpirationRegistry thread-safe (#5819)
This is an automated email from the ASF dual-hosted git repository.
rpuch pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/ignite-3.git
The following commit(s) were added to refs/heads/main by this push:
new f1730325375 IGNITE-25385 Make TransactionExpirationRegistry thread-safe (#5819)
f1730325375 is described below
commit f1730325375d3c0886f8b69511e568a4bfe3eb23
Author: Roman Puchkovskiy <ro...@gmail.com>
AuthorDate: Thu May 15 21:48:30 2025 +0400
IGNITE-25385 Make TransactionExpirationRegistry thread-safe (#5819)
---
.../tx/impl/TransactionExpirationRegistry.java | 28 +++++++++++++++++-----
1 file changed, 22 insertions(+), 6 deletions(-)
diff --git a/modules/transactions/src/main/java/org/apache/ignite/internal/tx/impl/TransactionExpirationRegistry.java b/modules/transactions/src/main/java/org/apache/ignite/internal/tx/impl/TransactionExpirationRegistry.java
index afd20b579b2..5dec6555841 100644
--- a/modules/transactions/src/main/java/org/apache/ignite/internal/tx/impl/TransactionExpirationRegistry.java
+++ b/modules/transactions/src/main/java/org/apache/ignite/internal/tx/impl/TransactionExpirationRegistry.java
@@ -18,10 +18,11 @@
package org.apache.ignite.internal.tx.impl;
import java.util.ArrayList;
-import java.util.HashSet;
import java.util.List;
import java.util.NavigableMap;
+import java.util.NoSuchElementException;
import java.util.Set;
+import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentSkipListMap;
import org.apache.ignite.internal.hlc.HybridTimestamp;
import org.apache.ignite.internal.logger.IgniteLogger;
@@ -91,7 +92,10 @@ class TransactionExpirationRegistry {
if (txOrSet instanceof Set) {
txsExpiringAtTs = (Set<InternalTransaction>) txOrSet;
} else {
- txsExpiringAtTs = new HashSet<>();
+ // Using a concurrent set because txsByExpirationTime does not guarantee linearization of compute() calls,
+ // so the set might be accessed/updated concurrently. It's not a problem to use a mutable set here as both
+ // addition to it and removal from it are idempotent.
+ txsExpiringAtTs = ConcurrentHashMap.newKeySet();
txsExpiringAtTs.add((InternalTransaction) txOrSet);
}
@@ -160,15 +164,27 @@ class TransactionExpirationRegistry {
set.remove(tx);
- return set.size() == 1 ? set.iterator().next() : set;
+ int newSize = set.size();
+
+ if (newSize == 0) {
+ return null;
+ } else if (newSize == 1) {
+ try {
+ return set.iterator().next();
+ } catch (NoSuchElementException e) {
+ return null;
+ }
+ } else {
+ return set;
+ }
} else {
- InternalTransaction tx0 = (InternalTransaction) txOrSet;
+ InternalTransaction registeredTx = (InternalTransaction) txOrSet;
- if (tx0.id().equals(tx.id())) {
+ if (registeredTx.id().equals(tx.id())) {
return null;
}
- return tx0;
+ return registeredTx;
}
});
}