Skip to content

Commit

Permalink
IGNITE-23110 Disallow IgniteCache#clear() within transaction
Browse files Browse the repository at this point in the history
  • Loading branch information
J-Bakuli committed Oct 2, 2024
1 parent 03bbc2d commit fe43f8e
Show file tree
Hide file tree
Showing 2 changed files with 44 additions and 3 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -152,6 +152,7 @@
import org.apache.ignite.thread.IgniteThreadFactory;
import org.apache.ignite.transactions.Transaction;
import org.apache.ignite.transactions.TransactionConcurrency;
import org.apache.ignite.transactions.TransactionException;
import org.apache.ignite.transactions.TransactionIsolation;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
Expand Down Expand Up @@ -1113,9 +1114,13 @@ private IgniteInternalFuture<?> clearAsync(@Nullable final Set<? extends K> keys
* @param near Near cache flag.
* @return Future.
*/
private IgniteInternalFuture<?> executeClearTask(@Nullable Set<? extends K> keys, boolean near) {
private IgniteInternalFuture<?> executeClearTask(@Nullable Set<? extends K> keys, boolean near) throws TransactionException {
Collection<ClusterNode> srvNodes = ctx.grid().cluster().forCacheNodes(name(), !near, near, false).nodes();

if (ctx.transactional() && ctx.grid().transactions().tx() != null && keys == null)
throw new IgniteException("Failed to invoke a non-transactional operation within a transaction: " +
"IgniteCache.clear().");

if (!srvNodes.isEmpty()) {
return ctx.kernalContext().task().execute(
new ClearTask(ctx.name(), ctx.affinity().affinityTopologyVersion(), keys, near),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,18 +28,25 @@
import org.apache.ignite.IgniteException;
import org.apache.ignite.configuration.CacheConfiguration;
import org.apache.ignite.configuration.IgniteConfiguration;
import org.apache.ignite.internal.IgniteEx;
import org.apache.ignite.testframework.GridTestUtils;
import org.apache.ignite.testframework.junits.common.GridCommonAbstractTest;
import org.apache.ignite.transactions.Transaction;
import org.junit.Test;

import static org.apache.ignite.cache.CacheAtomicityMode.ATOMIC;
import static org.apache.ignite.cache.CacheAtomicityMode.TRANSACTIONAL;
import static org.apache.ignite.cache.CachePeekMode.ALL;
import static org.apache.ignite.transactions.TransactionConcurrency.PESSIMISTIC;
import static org.apache.ignite.transactions.TransactionIsolation.READ_COMMITTED;

/**
* Checks how atomic cache operations work within a transaction.
* Checks how atomic and transactional cache operations work within a transaction.
*/
public class AtomicOperationsInTxTest extends GridCommonAbstractTest {
/** */
protected static IgniteEx client;

/** {@inheritDoc} */
@Override protected IgniteConfiguration getConfiguration(String gridName) throws Exception {
IgniteConfiguration cfg = super.getConfiguration(gridName);
Expand All @@ -57,11 +64,13 @@ public class AtomicOperationsInTxTest extends GridCommonAbstractTest {
/** {@inheritDoc} */
@Override protected void beforeTest() throws Exception {
startGrid(0);

client = startClientGrid("client");
}

/** {@inheritDoc} */
@Override protected void afterTest() throws Exception {
stopGrid(0);
stopAllGrids();
}

/**
Expand Down Expand Up @@ -136,6 +145,33 @@ public void testSetOfAtomicOperationsWithinTransactions() {
checkLock();
}

/**
* Tests that a non-transactional cache operation {@link IgniteCache#clear() is not allowed within transactions.
*/
@Test
public void testClearInTransaction() {
IgniteCache<Object, Object> cache = client.createCache(new CacheConfiguration<>("my-cache")
.setAtomicityMode(TRANSACTIONAL));

cache.put(1, 1);

try (Transaction tx = client.transactions().txStart(PESSIMISTIC, READ_COMMITTED)) {
cache.put(2, 2);

cache.clear();

tx.commit();
}
catch (IgniteException e) {
assertTrue(e.getMessage().startsWith("Failed to invoke a non-transactional operation within a transaction: " +
"IgniteCache.clear()."));
}

assertTrue(cache.containsKey(1));

assertFalse(cache.containsKey(2));
}

/**
* Otherwise - it should throw exception.
* @param op Operation.
Expand Down

0 comments on commit fe43f8e

Please sign in to comment.