Repository: ignite
Updated Branches:
  refs/heads/ignite-8446 [created] 48949b8f2


IGNITE-8446 Ability to check and completely fill transactions on creation

Signed-off-by: Anton Vinogradov <[email protected]>


Project: http://git-wip-us.apache.org/repos/asf/ignite/repo
Commit: http://git-wip-us.apache.org/repos/asf/ignite/commit/48949b8f
Tree: http://git-wip-us.apache.org/repos/asf/ignite/tree/48949b8f
Diff: http://git-wip-us.apache.org/repos/asf/ignite/diff/48949b8f

Branch: refs/heads/ignite-8446
Commit: 48949b8f236ec6df6f8a816ee3f9ac827f2f492d
Parents: 381448e
Author: Anton Vinogradov <[email protected]>
Authored: Mon May 21 13:02:41 2018 +0300
Committer: Anton Vinogradov <[email protected]>
Committed: Mon May 21 13:02:41 2018 +0300

----------------------------------------------------------------------
 .../org/apache/ignite/events/EventType.java     | 23 +++++
 .../apache/ignite/events/TransactionEvent.java  | 55 ++++++++++++
 .../transactions/IgniteTransactionsImpl.java    | 11 ++-
 .../cache/transactions/TxLabelTest.java         | 94 +++++++++++++++++++-
 4 files changed, 178 insertions(+), 5 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ignite/blob/48949b8f/modules/core/src/main/java/org/apache/ignite/events/EventType.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/events/EventType.java 
b/modules/core/src/main/java/org/apache/ignite/events/EventType.java
index b0b410a..113c53d 100644
--- a/modules/core/src/main/java/org/apache/ignite/events/EventType.java
+++ b/modules/core/src/main/java/org/apache/ignite/events/EventType.java
@@ -781,6 +781,18 @@ public interface EventType {
     public static final int EVT_WAL_SEGMENT_ARCHIVED = 128;
 
     /**
+     * Built-in event type: Transaction has been started.
+     * <p>
+     * Fired for each started transactions except system transactions.
+     * <p>
+     * NOTE: all types in range <b>from 1 to 1000 are reserved</b> for
+     * internal Ignite events and should not be used by user-defined events.
+     *
+     * @see WalSegmentArchivedEvent
+     */
+    public static final int EVT_TX_STARTED = 129;
+
+    /**
      * All checkpoint events. This array can be directly passed into
      * {@link IgniteEvents#localListen(IgnitePredicate, int...)} method to
      * subscribe to all checkpoint events.
@@ -979,6 +991,17 @@ public interface EventType {
     };
 
     /**
+     * All Transaction events. This array can be directly passed into
+     * {@link IgniteEvents#localListen(IgnitePredicate, int...)} method to
+     * subscribe to all transaction events.
+     *
+     * @see TransactionEvent
+     */
+    public static final int[] EVTS_TX = {
+        EVT_TX_STARTED
+    };
+
+    /**
      * All Ignite events (<b>including</b> metric update event).
      */
     public static final int[] EVTS_ALL = U.gridEvents();

http://git-wip-us.apache.org/repos/asf/ignite/blob/48949b8f/modules/core/src/main/java/org/apache/ignite/events/TransactionEvent.java
----------------------------------------------------------------------
diff --git 
a/modules/core/src/main/java/org/apache/ignite/events/TransactionEvent.java 
b/modules/core/src/main/java/org/apache/ignite/events/TransactionEvent.java
new file mode 100644
index 0000000..deb9019
--- /dev/null
+++ b/modules/core/src/main/java/org/apache/ignite/events/TransactionEvent.java
@@ -0,0 +1,55 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ignite.events;
+
+import org.apache.ignite.cluster.ClusterNode;
+import 
org.apache.ignite.internal.processors.cache.transactions.IgniteInternalTx;
+
+/**
+ * Event indicates there was some action with transaction, eg. creation, 
rollback, commit and etc.
+ *
+ * @see EventType#EVTS_TX
+ */
+public class TransactionEvent extends EventAdapter {
+    /** */
+    private static final long serialVersionUID = 0L;
+
+    /** Tx. */
+    private IgniteInternalTx tx;
+
+    /**
+     * @param node Node.
+     * @param msg Message.
+     * @param type Type.
+     * @param tx Tx.
+     */
+    public TransactionEvent(ClusterNode node, String msg, int type, 
IgniteInternalTx tx) {
+        super(node, msg, type);
+
+        assert tx != null;
+
+        this.tx = tx;
+    }
+
+    /**
+     *
+     */
+    public IgniteInternalTx tx() {
+        return tx;
+    }
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/48949b8f/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteTransactionsImpl.java
----------------------------------------------------------------------
diff --git 
a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteTransactionsImpl.java
 
b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteTransactionsImpl.java
index 25ba849..985dd25 100644
--- 
a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteTransactionsImpl.java
+++ 
b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteTransactionsImpl.java
@@ -20,7 +20,9 @@ package 
org.apache.ignite.internal.processors.cache.transactions;
 import java.util.Collection;
 import org.apache.ignite.IgniteTransactions;
 import org.apache.ignite.configuration.TransactionConfiguration;
+import org.apache.ignite.events.TransactionEvent;
 import org.apache.ignite.internal.IgniteTransactionsEx;
+import 
org.apache.ignite.internal.managers.eventstorage.GridEventStorageManager;
 import org.apache.ignite.internal.processors.cache.GridCacheContext;
 import org.apache.ignite.internal.processors.cache.GridCacheSharedContext;
 import 
org.apache.ignite.internal.processors.cache.distributed.near.GridNearTxLocal;
@@ -31,11 +33,13 @@ import org.apache.ignite.lang.IgniteClosure;
 import org.apache.ignite.lang.IgnitePredicate;
 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.apache.ignite.transactions.TransactionMetrics;
-import org.apache.ignite.transactions.TransactionException;
 import org.jetbrains.annotations.Nullable;
 
+import static org.apache.ignite.events.EventType.EVT_TX_STARTED;
+
 /**
  * Grid transactions implementation.
  */
@@ -181,6 +185,11 @@ public class IgniteTransactionsImpl<K, V> implements 
IgniteTransactionsEx {
 
             assert tx != null;
 
+            GridEventStorageManager evt = cctx.gridEvents();
+
+            if (sysCacheCtx == null /* ignoring system tx */ && 
evt.isRecordable(EVT_TX_STARTED))
+                evt.record(new TransactionEvent(cctx.discovery().localNode(), 
null, EVT_TX_STARTED, tx));
+
             return tx;
         }
         finally {

http://git-wip-us.apache.org/repos/asf/ignite/blob/48949b8f/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/transactions/TxLabelTest.java
----------------------------------------------------------------------
diff --git 
a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/transactions/TxLabelTest.java
 
b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/transactions/TxLabelTest.java
index d89ba0b..c442357 100644
--- 
a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/transactions/TxLabelTest.java
+++ 
b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/transactions/TxLabelTest.java
@@ -17,14 +17,28 @@
 
 package org.apache.ignite.internal.processors.cache.transactions;
 
+import java.util.concurrent.atomic.AtomicReference;
 import org.apache.ignite.Ignite;
+import org.apache.ignite.IgniteEvents;
+import org.apache.ignite.events.Event;
+import org.apache.ignite.events.TransactionEvent;
 import org.apache.ignite.internal.processors.cache.GridCacheAbstractSelfTest;
+import 
org.apache.ignite.internal.processors.cache.distributed.near.GridNearTxLocal;
+import org.apache.ignite.lang.IgnitePredicate;
 import org.apache.ignite.transactions.Transaction;
 
+import static org.apache.ignite.events.EventType.EVTS_TX;
+import static org.apache.ignite.events.EventType.EVT_TX_STARTED;
+
 /**
  * Tests transaction labels.
  */
 public class TxLabelTest extends GridCacheAbstractSelfTest {
+    /** {@inheritDoc} */
+    @Override protected int gridCount() {
+        return 1;
+    }
+
     /**
      * Tests transaction labels.
      */
@@ -47,7 +61,7 @@ public class TxLabelTest extends GridCacheAbstractSelfTest {
      * @param lbl Label.
      */
     private void testLabel0(Ignite ignite, String lbl) {
-        try(Transaction tx = ignite.transactions().withLabel(lbl).txStart()) {
+        try (Transaction tx = ignite.transactions().withLabel(lbl).txStart()) {
             assertEquals(lbl, tx.label());
 
             ignite.cache(DEFAULT_CACHE_NAME).put(0, 0);
@@ -56,8 +70,80 @@ public class TxLabelTest extends GridCacheAbstractSelfTest {
         }
     }
 
-    /** {@inheritDoc} */
-    @Override protected int gridCount() {
-        return 1;
+    /**
+     *
+     */
+    public void testLabelFilledCheck() {
+        Ignite ignite = grid(0);
+
+        final IgniteEvents evts = ignite.events();
+
+        evts.enableLocal(EVTS_TX);
+
+        AtomicReference<Throwable> ref = new AtomicReference<>();
+
+        evts.localListen((IgnitePredicate<Event>)e -> {
+            assert e instanceof TransactionEvent;
+
+            TransactionEvent evt = (TransactionEvent)e;
+
+            if (((GridNearTxLocal)(evt.tx())).label() == null)
+                ref.set(new IllegalStateException("Label should be filled!"));
+
+            return true;
+        }, EVT_TX_STARTED);
+
+        assertNull(ref.get());
+
+        try (Transaction tx = 
ignite.transactions().withLabel("test").txStart()) {
+            // No-op.
+        }
+
+        assertNull(ref.get());
+
+        try (Transaction tx = ignite.transactions().txStart()) {
+            // No-op.
+        }
+
+        assertNotNull(ref.get());
+    }
+
+    /**
+     *
+     */
+    public void testLabelFilledGuarantee() {
+        Ignite ignite = grid(0);
+
+        final IgniteEvents evts = ignite.events();
+
+        evts.enableLocal(EVTS_TX);
+
+        class LabelNotFilledError extends Error {
+            private LabelNotFilledError(String msg) {
+                super(msg);
+            }
+        }
+
+        evts.localListen((IgnitePredicate<Event>)e -> {
+            assert e instanceof TransactionEvent;
+
+            TransactionEvent evt = (TransactionEvent)e;
+
+            if (((GridNearTxLocal)(evt.tx())).label() == null)
+                throw new LabelNotFilledError("Label should be filled!");
+
+            return true;
+        }, EVT_TX_STARTED);
+
+        try (Transaction tx = 
ignite.transactions().withLabel("test").txStart()) {
+            // No-op.
+        }
+
+        try (Transaction tx = ignite.transactions().txStart()) {
+            fail("Should fail prior this line.");
+        }
+        catch (LabelNotFilledError e) {
+            // No-op.
+        }
     }
 }

Reply via email to