This is an automated email from the ASF dual-hosted git repository.

timoninmaxim pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/ignite.git


The following commit(s) were added to refs/heads/master by this push:
     new 319250b7a8e IGNITE-23681 Disallow IgniteCache#removeAll() within 
transaction (#11713)
319250b7a8e is described below

commit 319250b7a8ede78e84f3fd038321694964eed2f4
Author: Julia Bakulina <[email protected]>
AuthorDate: Wed Dec 25 14:29:57 2024 +0300

    IGNITE-23681 Disallow IgniteCache#removeAll() within transaction (#11713)
---
 .../common/CacheEventSecurityContextTest.java      |  6 --
 .../main/java/org/apache/ignite/IgniteCache.java   |  2 +
 .../internal/client/thin/TcpClientCache.java       | 25 +++---
 .../processors/cache/GridCacheAdapter.java         |  4 +-
 .../distributed/GridDistributedCacheAdapter.java   | 11 +++
 .../internal/client/thin/BlockingTxOpsTest.java    |  7 --
 ...inClientNonTransactionalOperationsInTxTest.java | 66 +++++++++++++---
 .../NonTransactionalOperationsInTxTest.java        | 89 ++++++++++++++++++----
 8 files changed, 162 insertions(+), 48 deletions(-)

diff --git 
a/modules/clients/src/test/java/org/apache/ignite/common/CacheEventSecurityContextTest.java
 
b/modules/clients/src/test/java/org/apache/ignite/common/CacheEventSecurityContextTest.java
index 83959564f24..5aa08953203 100644
--- 
a/modules/clients/src/test/java/org/apache/ignite/common/CacheEventSecurityContextTest.java
+++ 
b/modules/clients/src/test/java/org/apache/ignite/common/CacheEventSecurityContextTest.java
@@ -203,9 +203,6 @@ public class CacheEventSecurityContextTest extends 
AbstractEventSecurityContextT
             checkEvents(cli, k -> cache.removeAll(of(k)), true, 
EVT_CACHE_OBJECT_REMOVED);
             checkEvents(cli, k -> cache.removeAllAsync(of(k)).get(), true, 
EVT_CACHE_OBJECT_REMOVED);
 
-            checkEvents(cli, k -> cache.removeAll(), true, 
EVT_CACHE_OBJECT_REMOVED);
-            checkEvents(cli, k -> cache.removeAllAsync().get(), true, 
EVT_CACHE_OBJECT_REMOVED);
-
             checkEvents(cli, k -> cache.putIfAbsent(k, "val"), false, 
EVT_CACHE_OBJECT_PUT);
             checkEvents(cli, k -> cache.putIfAbsentAsync(k, "val").get(), 
false, EVT_CACHE_OBJECT_PUT);
 
@@ -342,9 +339,6 @@ public class CacheEventSecurityContextTest extends 
AbstractEventSecurityContextT
         checkEvents(ignite, k -> cache.removeAll(of(k)), true, 
EVT_CACHE_OBJECT_REMOVED);
         checkEvents(ignite, k -> cache.removeAllAsync(of(k)).get(), true, 
EVT_CACHE_OBJECT_REMOVED);
 
-        checkEvents(ignite, k -> cache.removeAll(), true, 
EVT_CACHE_OBJECT_REMOVED);
-        checkEvents(ignite, k -> cache.removeAllAsync().get(), true, 
EVT_CACHE_OBJECT_REMOVED);
-
         checkEvents(ignite, k -> cache.putIfAbsent(k, "val"), false, 
EVT_CACHE_OBJECT_PUT);
         checkEvents(ignite, k -> cache.putIfAbsentAsync(k, "val").get(), 
false, EVT_CACHE_OBJECT_PUT);
 
diff --git a/modules/core/src/main/java/org/apache/ignite/IgniteCache.java 
b/modules/core/src/main/java/org/apache/ignite/IgniteCache.java
index 2ed4ef2d070..1bfa2f0f6e8 100644
--- a/modules/core/src/main/java/org/apache/ignite/IgniteCache.java
+++ b/modules/core/src/main/java/org/apache/ignite/IgniteCache.java
@@ -1193,6 +1193,8 @@ public interface IgniteCache<K, V> extends 
javax.cache.Cache<K, V>, IgniteAsyncS
      * </ul>
      * If the cache is empty, the {@link CacheWriter} is not called.
      * <p>
+     * This operation is not transactional. It calls broadcast closure that 
deletes all primary keys from remote nodes.
+     * <p>
      * This is potentially an expensive operation as listeners are invoked.
      * Use {@link #clearAsync()} to avoid this.
      *
diff --git 
a/modules/core/src/main/java/org/apache/ignite/internal/client/thin/TcpClientCache.java
 
b/modules/core/src/main/java/org/apache/ignite/internal/client/thin/TcpClientCache.java
index 07837c41d17..9a1fc43c34c 100644
--- 
a/modules/core/src/main/java/org/apache/ignite/internal/client/thin/TcpClientCache.java
+++ 
b/modules/core/src/main/java/org/apache/ignite/internal/client/thin/TcpClientCache.java
@@ -123,9 +123,9 @@ public class TcpClientCache<K, V> implements ClientCache<K, 
V> {
     /** JCache adapter. */
     private final Cache<K, V> jCacheAdapter;
 
-    /** Exception thrown when a non-transactional ClientCache clear operation 
is invoked within a transaction. */
-    public static final String 
NON_TRANSACTIONAL_CLIENT_CACHE_CLEAR_IN_TX_ERROR_MESSAGE = "Failed to invoke a 
" +
-        "non-transactional ClientCache clear operation within a transaction.";
+    /** Exception thrown when a non-transactional ClientCache operation is 
invoked within a transaction. */
+    public static final String 
NON_TRANSACTIONAL_CLIENT_CACHE_IN_TX_ERROR_MESSAGE = "Failed to invoke a " +
+        "non-transactional ClientCache %s operation within a transaction.";
 
     /** Constructor. */
     TcpClientCache(String name, ReliableChannel ch, ClientBinaryMarshaller 
marsh, TcpClientTransactions transactions,
@@ -555,11 +555,17 @@ public class TcpClientCache<K, V> implements 
ClientCache<K, V> {
 
     /** {@inheritDoc} */
     @Override public void removeAll() throws ClientException {
+        if (transactions.tx() != null)
+            throw new 
CacheException(String.format(NON_TRANSACTIONAL_CLIENT_CACHE_IN_TX_ERROR_MESSAGE,
 "removeAll"));
+
         ch.request(ClientOperation.CACHE_REMOVE_ALL, this::writeCacheInfo);
     }
 
     /** {@inheritDoc} */
     @Override public IgniteClientFuture<Void> removeAllAsync() throws 
ClientException {
+        if (transactions.tx() != null)
+            throw new 
CacheException(String.format(NON_TRANSACTIONAL_CLIENT_CACHE_IN_TX_ERROR_MESSAGE,
 "removeAllAsync"));
+
         return ch.requestAsync(ClientOperation.CACHE_REMOVE_ALL, 
this::writeCacheInfo);
     }
 
@@ -728,7 +734,7 @@ public class TcpClientCache<K, V> implements ClientCache<K, 
V> {
      */
     @Override public void clear() throws ClientException {
         if (transactions.tx() != null)
-            throw new 
CacheException(NON_TRANSACTIONAL_CLIENT_CACHE_CLEAR_IN_TX_ERROR_MESSAGE);
+            throw new 
CacheException(String.format(NON_TRANSACTIONAL_CLIENT_CACHE_IN_TX_ERROR_MESSAGE,
 "clear"));
 
         ch.request(ClientOperation.CACHE_CLEAR, this::writeCacheInfo);
     }
@@ -745,7 +751,7 @@ public class TcpClientCache<K, V> implements ClientCache<K, 
V> {
      */
     @Override public IgniteClientFuture<Void> clearAsync() throws 
ClientException {
         if (transactions.tx() != null)
-            throw new 
CacheException(NON_TRANSACTIONAL_CLIENT_CACHE_CLEAR_IN_TX_ERROR_MESSAGE);
+            throw new 
CacheException(String.format(NON_TRANSACTIONAL_CLIENT_CACHE_IN_TX_ERROR_MESSAGE,
 "clearAsync"));
 
         return ch.requestAsync(ClientOperation.CACHE_CLEAR, 
this::writeCacheInfo);
     }
@@ -1366,7 +1372,7 @@ public class TcpClientCache<K, V> implements 
ClientCache<K, V> {
         // Transactional operation cannot be executed on affinity node, it 
should be executed on node started
         // the transaction.
         if (tx != null) {
-            checkTxClearOperation(op);
+            checkTxClearOperation(op, false);
 
             try {
                 return tx.clientChannel().service(op, payloadWriter, 
payloadReader);
@@ -1395,7 +1401,7 @@ public class TcpClientCache<K, V> implements 
ClientCache<K, V> {
         // Transactional operation cannot be executed on affinity node, it 
should be executed on node started
         // the transaction.
         if (tx != null) {
-            checkTxClearOperation(op);
+            checkTxClearOperation(op, true);
 
             CompletableFuture<T> fut = new CompletableFuture<>();
 
@@ -1420,9 +1426,10 @@ public class TcpClientCache<K, V> implements 
ClientCache<K, V> {
     }
 
     /** */
-    private void checkTxClearOperation(ClientOperation op) {
+    private void checkTxClearOperation(ClientOperation op, boolean async) {
         if (op == ClientOperation.CACHE_CLEAR_KEY || op == 
ClientOperation.CACHE_CLEAR_KEYS)
-            throw new 
CacheException(NON_TRANSACTIONAL_CLIENT_CACHE_CLEAR_IN_TX_ERROR_MESSAGE);
+            throw new 
CacheException(String.format(NON_TRANSACTIONAL_CLIENT_CACHE_IN_TX_ERROR_MESSAGE,
+                async ? "clearAsync" : "clear"));
     }
 
     /**
diff --git 
a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheAdapter.java
 
b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheAdapter.java
index fcafa530035..ba833764090 100644
--- 
a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheAdapter.java
+++ 
b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheAdapter.java
@@ -1125,7 +1125,7 @@ public abstract class GridCacheAdapter<K, V> implements 
IgniteInternalCache<K, V
      * @return Future.
      */
     private IgniteInternalFuture<?> executeClearTask(@Nullable Set<? extends 
K> keys, boolean near) {
-        if (ctx.transactional() && ctx.grid().transactions().tx() != null)
+        if (ctx.grid().transactions().tx() != null)
             throw new 
CacheException(NON_TRANSACTIONAL_IGNITE_CACHE_CLEAR_IN_TX_ERROR_MESSAGE);
 
         Collection<ClusterNode> srvNodes = 
ctx.grid().cluster().forCacheNodes(name(), !near, near, false).nodes();
@@ -4016,7 +4016,7 @@ public abstract class GridCacheAdapter<K, V> implements 
IgniteInternalCache<K, V
      * @param readers Whether to clear readers.
      */
     private boolean clearLocally0(K key, boolean readers) {
-        if (ctx.transactional() && ctx.grid().transactions().tx() != null)
+        if (ctx.grid().transactions().tx() != null)
             throw new 
CacheException(NON_TRANSACTIONAL_IGNITE_CACHE_CLEAR_IN_TX_ERROR_MESSAGE);
 
         ctx.shared().cache().checkReadOnlyState("clear", ctx.config());
diff --git 
a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/GridDistributedCacheAdapter.java
 
b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/GridDistributedCacheAdapter.java
index f33199bdc26..8d330906dd4 100644
--- 
a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/GridDistributedCacheAdapter.java
+++ 
b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/GridDistributedCacheAdapter.java
@@ -23,6 +23,7 @@ import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 import java.util.concurrent.atomic.AtomicReference;
+import javax.cache.CacheException;
 import org.apache.ignite.IgniteCheckedException;
 import org.apache.ignite.IgniteException;
 import org.apache.ignite.cache.CachePeekMode;
@@ -71,6 +72,10 @@ public abstract class GridDistributedCacheAdapter<K, V> 
extends GridCacheAdapter
     /** */
     private static final long serialVersionUID = 0L;
 
+    /** Exception thrown when a non-transactional IgniteCache operation is 
invoked within a transaction. */
+    public static final String 
NON_TRANSACTIONAL_IGNITE_CACHE_IN_TX_ERROR_MESSAGE = "Failed to invoke a " +
+        "non-transactional IgniteCache %s operation within a transaction.";
+
     /**
      * Empty constructor required by {@link Externalizable}.
      */
@@ -164,6 +169,9 @@ public abstract class GridDistributedCacheAdapter<K, V> 
extends GridCacheAdapter
 
     /** {@inheritDoc} */
     @Override public void removeAll() throws IgniteCheckedException {
+        if (ctx.grid().transactions().tx() != null)
+            throw new 
CacheException(String.format(NON_TRANSACTIONAL_IGNITE_CACHE_IN_TX_ERROR_MESSAGE,
 "removeAll"));
+
         try {
             AffinityTopologyVersion topVer;
 
@@ -201,6 +209,9 @@ public abstract class GridDistributedCacheAdapter<K, V> 
extends GridCacheAdapter
 
     /** {@inheritDoc} */
     @Override public IgniteInternalFuture<?> removeAllAsync() {
+        if (ctx.grid().transactions().tx() != null)
+            throw new 
CacheException(String.format(NON_TRANSACTIONAL_IGNITE_CACHE_IN_TX_ERROR_MESSAGE,
 "removeAllAsync"));
+
         GridFutureAdapter<Void> opFut = new GridFutureAdapter<>();
 
         AffinityTopologyVersion topVer = 
ctx.affinity().affinityTopologyVersion();
diff --git 
a/modules/core/src/test/java/org/apache/ignite/internal/client/thin/BlockingTxOpsTest.java
 
b/modules/core/src/test/java/org/apache/ignite/internal/client/thin/BlockingTxOpsTest.java
index d02c53bb034..ae45a7ca01a 100644
--- 
a/modules/core/src/test/java/org/apache/ignite/internal/client/thin/BlockingTxOpsTest.java
+++ 
b/modules/core/src/test/java/org/apache/ignite/internal/client/thin/BlockingTxOpsTest.java
@@ -181,13 +181,6 @@ public class BlockingTxOpsTest extends 
AbstractThinClientTest {
                         () -> assertEquals(0, cache.get(0))
                     );
 
-                    // Remove all operation.
-                    checkOpMultithreaded(client,
-                        () -> cache.putAll(F.asMap(0, 0, 1, 1)),
-                        () -> cache.removeAll(),
-                        () -> assertEquals(0, cache.size())
-                    );
-
                     // Remove if equals operation.
                     checkOpMultithreaded(client,
                         () -> cache.put(0, 0),
diff --git 
a/modules/core/src/test/java/org/apache/ignite/internal/client/thin/ThinClientNonTransactionalOperationsInTxTest.java
 
b/modules/core/src/test/java/org/apache/ignite/internal/client/thin/ThinClientNonTransactionalOperationsInTxTest.java
index aa26c8476db..0baeedc2915 100644
--- 
a/modules/core/src/test/java/org/apache/ignite/internal/client/thin/ThinClientNonTransactionalOperationsInTxTest.java
+++ 
b/modules/core/src/test/java/org/apache/ignite/internal/client/thin/ThinClientNonTransactionalOperationsInTxTest.java
@@ -33,7 +33,7 @@ import 
org.apache.ignite.testframework.junits.common.GridCommonAbstractTest;
 import org.junit.Test;
 
 import static org.apache.ignite.cache.CacheAtomicityMode.TRANSACTIONAL;
-import static 
org.apache.ignite.internal.client.thin.TcpClientCache.NON_TRANSACTIONAL_CLIENT_CACHE_CLEAR_IN_TX_ERROR_MESSAGE;
+import static 
org.apache.ignite.internal.client.thin.TcpClientCache.NON_TRANSACTIONAL_CLIENT_CACHE_IN_TX_ERROR_MESSAGE;
 import static 
org.apache.ignite.transactions.TransactionConcurrency.PESSIMISTIC;
 import static 
org.apache.ignite.transactions.TransactionIsolation.READ_COMMITTED;
 
@@ -55,29 +55,32 @@ public class ThinClientNonTransactionalOperationsInTxTest 
extends GridCommonAbst
     public void testThinClientCacheClear() throws Exception {
         startGrid(0);
 
-        IgniteClient client = Ignition.startClient(new 
ClientConfiguration().setAddresses(Config.SERVER));
+        try (IgniteClient client = Ignition.startClient(new 
ClientConfiguration().setAddresses(Config.SERVER))) {
 
-        checkThinClientCacheOperation(client, cache -> cache.clear());
+            checkThinClientCacheClearOperation(client, false, cache -> 
cache.clear());
 
-        checkThinClientCacheOperation(client, cache -> cache.clear(2));
+            checkThinClientCacheClearOperation(client, false, cache -> 
cache.clear(2));
 
-        checkThinClientCacheOperation(client, cache -> 
cache.clear(Collections.singleton(2)));
+            checkThinClientCacheClearOperation(client, false, cache -> 
cache.clear(Collections.singleton(2)));
 
-        checkThinClientCacheOperation(client, cache -> 
cache.clearAll(Collections.singleton(2)));
+            checkThinClientCacheClearOperation(client, false, cache -> 
cache.clearAll(Collections.singleton(2)));
 
-        checkThinClientCacheOperation(client, cache -> cache.clearAsync());
+            checkThinClientCacheClearOperation(client, true, cache -> 
cache.clearAsync());
 
-        checkThinClientCacheOperation(client, cache -> cache.clearAsync(2));
+            checkThinClientCacheClearOperation(client, true, cache -> 
cache.clearAsync(2));
 
-        checkThinClientCacheOperation(client, cache -> 
cache.clearAllAsync(Collections.singleton(2)));
+            checkThinClientCacheClearOperation(client, true, cache -> 
cache.clearAllAsync(Collections.singleton(2)));
+        }
     }
 
     /**
      * It should throw exception.
      *
      * @param client IgniteClient.
+     * @param async Async flag.
+     * @param op Operation.
      */
-    private void checkThinClientCacheOperation(IgniteClient client, 
Consumer<ClientCache<Object, Object>> op) {
+    private void checkThinClientCacheClearOperation(IgniteClient client, 
boolean async, Consumer<ClientCache<Object, Object>> op) {
         ClientCache<Object, Object> cache = client.cache(DEFAULT_CACHE_NAME);
 
         cache.put(1, 1);
@@ -90,7 +93,48 @@ public class ThinClientNonTransactionalOperationsInTxTest 
extends GridCommonAbst
             }
 
             return null;
-        }, CacheException.class, 
NON_TRANSACTIONAL_CLIENT_CACHE_CLEAR_IN_TX_ERROR_MESSAGE);
+        }, CacheException.class, 
String.format(NON_TRANSACTIONAL_CLIENT_CACHE_IN_TX_ERROR_MESSAGE,
+            async ? "clearAsync" : "clear"));
+
+        assertTrue(cache.containsKey(1));
+        assertFalse(cache.containsKey(2));
+    }
+
+    /** */
+    @Test
+    public void testThinClientCacheRemove() throws Exception {
+        startGrid(0);
+
+        try (IgniteClient client = Ignition.startClient(new 
ClientConfiguration().setAddresses(Config.SERVER))) {
+
+            checkThinClientCacheRemoveOperation(client, false, cache -> 
cache.removeAll());
+
+            checkThinClientCacheRemoveOperation(client, true, cache -> 
cache.removeAllAsync());
+        }
+    }
+
+    /**
+     * It should throw exception.
+     *
+     * @param client IgniteClient.
+     * @param async Async flag.
+     * @param op Operation.
+     */
+    private void checkThinClientCacheRemoveOperation(IgniteClient client, 
boolean async, Consumer<ClientCache<Object, Object>> op) {
+        ClientCache<Object, Object> cache = client.cache(DEFAULT_CACHE_NAME);
+
+        cache.put(1, 1);
+
+        GridTestUtils.assertThrows(log, (Callable<Void>)() -> {
+            try (ClientTransaction tx = 
client.transactions().txStart(PESSIMISTIC, READ_COMMITTED)) {
+                cache.put(2, 2);
+
+                op.accept(cache);
+            }
+
+            return null;
+        }, CacheException.class, 
String.format(NON_TRANSACTIONAL_CLIENT_CACHE_IN_TX_ERROR_MESSAGE,
+            async ? "removeAllAsync" : "removeAll"));
 
         assertTrue(cache.containsKey(1));
         assertFalse(cache.containsKey(2));
diff --git 
a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/transactions/NonTransactionalOperationsInTxTest.java
 
b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/transactions/NonTransactionalOperationsInTxTest.java
index 94d6796dba6..fa2231501b8 100644
--- 
a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/transactions/NonTransactionalOperationsInTxTest.java
+++ 
b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/transactions/NonTransactionalOperationsInTxTest.java
@@ -29,6 +29,7 @@ import org.junit.Test;
 
 import static org.apache.ignite.cache.CacheAtomicityMode.TRANSACTIONAL;
 import static 
org.apache.ignite.internal.processors.cache.GridCacheAdapter.NON_TRANSACTIONAL_IGNITE_CACHE_CLEAR_IN_TX_ERROR_MESSAGE;
+import static 
org.apache.ignite.internal.processors.cache.distributed.GridDistributedCacheAdapter.NON_TRANSACTIONAL_IGNITE_CACHE_IN_TX_ERROR_MESSAGE;
 import static org.apache.ignite.testframework.GridTestUtils.assertThrows;
 
 /** Checks that non-transactional cache operations fail within a transaction. 
*/
@@ -68,35 +69,38 @@ public class NonTransactionalOperationsInTxTest extends 
GridCommonAbstractTest {
      * @param ignite Ignite.
      */
     private void checkClearOperation(IgniteEx ignite) {
-        checkIgniteCacheOperation(ignite, false, cache -> cache.clear());
+        checkIgniteCacheClearOperation(ignite, false, false, cache -> 
cache.clear());
 
-        checkIgniteCacheOperation(ignite, false, cache -> cache.clear(2));
+        checkIgniteCacheClearOperation(ignite, false, false, cache -> 
cache.clear(2));
 
-        checkIgniteCacheOperation(ignite, false, cache -> 
cache.clear(Collections.singleton(2)));
+        checkIgniteCacheClearOperation(ignite, false, false, cache -> 
cache.clear(Collections.singleton(2)));
 
-        checkIgniteCacheOperation(ignite, false, cache -> 
cache.clearAll(Collections.singleton(2)));
+        checkIgniteCacheClearOperation(ignite, false, false, cache -> 
cache.clearAll(Collections.singleton(2)));
 
-        checkIgniteCacheOperation(ignite, false, cache -> cache.clearAsync());
+        checkIgniteCacheClearOperation(ignite, true, false, cache -> 
cache.clearAsync());
 
-        checkIgniteCacheOperation(ignite, false, cache -> cache.clearAsync(2));
+        checkIgniteCacheClearOperation(ignite, true, false, cache -> 
cache.clearAsync(2));
 
-        checkIgniteCacheOperation(ignite, false, cache -> 
cache.clearAllAsync(Collections.singleton(2)));
+        checkIgniteCacheClearOperation(ignite, true, false, cache -> 
cache.clearAllAsync(Collections.singleton(2)));
 
-        checkIgniteCacheOperation(ignite, true, cache -> cache.localClear(2));
+        checkIgniteCacheClearOperation(ignite, false, true, cache -> 
cache.localClear(2));
 
-        checkIgniteCacheOperation(ignite, true, cache -> 
cache.localClearAll(Collections.singleton(2)));
+        checkIgniteCacheClearOperation(ignite, false, true, cache -> 
cache.localClearAll(Collections.singleton(2)));
 
-        checkIgniteCacheOperation(ignite, false, cache -> cache.localClear(2));
+        checkIgniteCacheClearOperation(ignite, false, false, cache -> 
cache.localClear(2));
 
-        checkIgniteCacheOperation(ignite, false, cache -> 
cache.localClearAll(Collections.singleton(2)));
+        checkIgniteCacheClearOperation(ignite, false, false, cache -> 
cache.localClearAll(Collections.singleton(2)));
     }
 
     /**
      * It should throw exception.
      *
      * @param ignite Ignite.
+     * @param near Near flag.
+     * @param op Operation.
      */
-    private void checkIgniteCacheOperation(IgniteEx ignite, boolean near, 
Consumer<IgniteCache<Object, Object>> op) {
+    private void checkIgniteCacheClearOperation(IgniteEx ignite, boolean 
async, boolean near,
+        Consumer<IgniteCache<Object, Object>> op) {
         IgniteCache<Object, Object> cache;
 
         if (near)
@@ -115,7 +119,66 @@ public class NonTransactionalOperationsInTxTest extends 
GridCommonAbstractTest {
                 return null;
             }),
             CacheException.class,
-            NON_TRANSACTIONAL_IGNITE_CACHE_CLEAR_IN_TX_ERROR_MESSAGE
+            
String.format(NON_TRANSACTIONAL_IGNITE_CACHE_CLEAR_IN_TX_ERROR_MESSAGE, async ? 
"clearAsync" : "clear")
+        );
+
+        assertTrue(cache.containsKey(1));
+
+        assertFalse(cache.containsKey(2));
+    }
+
+    /** */
+    @Test
+    public void testIgniteCacheRemove() throws Exception {
+        startGrid(0);
+
+        checkRemoveOperation(grid(0));
+    }
+
+    /** */
+    @Test
+    public void testIgniteCacheRemoveOnClientNode() throws Exception {
+        startGrid(0);
+
+        startClientGrid(1);
+
+        checkRemoveOperation(grid(1));
+    }
+
+    /**
+     * It should throw exception.
+     *
+     * @param ignite Ignite.
+     */
+    private void checkRemoveOperation(IgniteEx ignite) {
+        checkIgniteCacheRemoveOperation(ignite, false, cache -> 
cache.removeAll());
+
+        checkIgniteCacheRemoveOperation(ignite, true, cache -> 
cache.removeAllAsync());
+    }
+
+    /**
+     * It should throw exception.
+     *
+     * @param ignite Ignite.
+     * @param async Async flag.
+     * @param op Operation.
+     */
+    private void checkIgniteCacheRemoveOperation(IgniteEx ignite, boolean 
async,
+        Consumer<IgniteCache<Object, Object>> op) {
+        IgniteCache<Object, Object> cache = ignite.cache(DEFAULT_CACHE_NAME);
+
+        cache.put(1, 1);
+
+        assertThrows(null,
+            () -> doInTransaction(ignite, () -> {
+                cache.put(2, 2);
+
+                op.accept(cache);
+
+                return null;
+            }),
+            CacheException.class,
+            String.format(NON_TRANSACTIONAL_IGNITE_CACHE_IN_TX_ERROR_MESSAGE, 
async ? "removeAllAsync" : "removeAll")
         );
 
         assertTrue(cache.containsKey(1));

Reply via email to