Search in sources :

Example 36 with GridCacheVersion

use of org.apache.ignite.internal.processors.cache.version.GridCacheVersion in project ignite by apache.

the class IgniteTxAdapter method batchStoreCommit.

/**
 * Performs batch database operations. This commit must be called
 * before cache update. This way if there is a DB failure,
 * cache transaction can still be rolled back.
 *
 * @param writeEntries Transaction write set.
 * @throws IgniteCheckedException If batch update failed.
 */
@SuppressWarnings({ "CatchGenericClass" })
protected final void batchStoreCommit(Iterable<IgniteTxEntry> writeEntries) throws IgniteCheckedException {
    if (!storeEnabled() || internal() || // No need to work with local store at GridNearTxRemote.
    (!local() && near()))
        return;
    Collection<CacheStoreManager> stores = txState().stores(cctx);
    if (stores == null || stores.isEmpty())
        return;
    assert isWriteToStoreFromDhtValid(stores) : "isWriteToStoreFromDht can't be different within one transaction";
    CacheStoreManager first = F.first(stores);
    boolean isWriteToStoreFromDht = first.isWriteToStoreFromDht();
    if ((local() || first.isLocal()) && (near() || isWriteToStoreFromDht)) {
        try {
            if (writeEntries != null) {
                Map<KeyCacheObject, IgniteBiTuple<? extends CacheObject, GridCacheVersion>> putMap = null;
                List<KeyCacheObject> rmvCol = null;
                CacheStoreManager writeStore = null;
                boolean skipNonPrimary = near() && isWriteToStoreFromDht;
                for (IgniteTxEntry e : writeEntries) {
                    boolean skip = e.skipStore();
                    if (!skip && skipNonPrimary) {
                        skip = e.cached().isNear() || e.cached().detached() || !e.context().affinity().primaryByPartition(e.cached().partition(), topologyVersion()).isLocal();
                    }
                    if (// Update local store at backups only if needed.
                    !skip && !local() && cctx.localStorePrimaryOnly())
                        skip = true;
                    if (skip)
                        continue;
                    boolean intercept = e.context().config().getInterceptor() != null;
                    if (intercept || !F.isEmpty(e.entryProcessors()))
                        e.cached().unswap(false);
                    IgniteBiTuple<GridCacheOperation, CacheObject> res = applyTransformClosures(e, false, null);
                    GridCacheContext cacheCtx = e.context();
                    GridCacheOperation op = res.get1();
                    KeyCacheObject key = e.key();
                    CacheObject val = res.get2();
                    GridCacheVersion ver = writeVersion();
                    if (op == CREATE || op == UPDATE) {
                        // Batch-process all removes if needed.
                        if (rmvCol != null && !rmvCol.isEmpty()) {
                            assert writeStore != null;
                            writeStore.removeAll(this, rmvCol);
                            // Reset.
                            rmvCol.clear();
                            writeStore = null;
                        }
                        // Batch-process puts if cache ID has changed.
                        if (writeStore != null && writeStore != cacheCtx.store()) {
                            if (putMap != null && !putMap.isEmpty()) {
                                writeStore.putAll(this, putMap);
                                // Reset.
                                putMap.clear();
                            }
                            writeStore = null;
                        }
                        if (intercept) {
                            Object interceptorVal = cacheCtx.config().getInterceptor().onBeforePut(new CacheLazyEntry(cacheCtx, key, e.cached().rawGet(), e.keepBinary()), cacheCtx.cacheObjectContext().unwrapBinaryIfNeeded(val, e.keepBinary(), false));
                            if (interceptorVal == null)
                                continue;
                            val = cacheCtx.toCacheObject(cacheCtx.unwrapTemporary(interceptorVal));
                        }
                        if (writeStore == null)
                            writeStore = cacheCtx.store();
                        if (writeStore.isWriteThrough()) {
                            if (putMap == null)
                                putMap = new LinkedHashMap<>(writeMap().size(), 1.0f);
                            putMap.put(key, F.t(val, ver));
                        }
                    } else if (op == DELETE) {
                        // Batch-process all puts if needed.
                        if (putMap != null && !putMap.isEmpty()) {
                            assert writeStore != null;
                            writeStore.putAll(this, putMap);
                            // Reset.
                            putMap.clear();
                            writeStore = null;
                        }
                        if (writeStore != null && writeStore != cacheCtx.store()) {
                            if (rmvCol != null && !rmvCol.isEmpty()) {
                                writeStore.removeAll(this, rmvCol);
                                // Reset.
                                rmvCol.clear();
                            }
                            writeStore = null;
                        }
                        if (intercept) {
                            IgniteBiTuple<Boolean, Object> t = cacheCtx.config().getInterceptor().onBeforeRemove(new CacheLazyEntry(cacheCtx, key, e.cached().rawGet(), e.keepBinary()));
                            if (cacheCtx.cancelRemove(t))
                                continue;
                        }
                        if (writeStore == null)
                            writeStore = cacheCtx.store();
                        if (writeStore.isWriteThrough()) {
                            if (rmvCol == null)
                                rmvCol = new ArrayList<>();
                            rmvCol.add(key);
                        }
                    } else if (log.isDebugEnabled())
                        log.debug("Ignoring NOOP entry for batch store commit: " + e);
                }
                if (putMap != null && !putMap.isEmpty()) {
                    assert rmvCol == null || rmvCol.isEmpty();
                    assert writeStore != null;
                    // Batch put at the end of transaction.
                    writeStore.putAll(this, putMap);
                }
                if (rmvCol != null && !rmvCol.isEmpty()) {
                    assert putMap == null || putMap.isEmpty();
                    assert writeStore != null;
                    // Batch remove at the end of transaction.
                    writeStore.removeAll(this, rmvCol);
                }
            }
            // Commit while locks are held.
            sessionEnd(stores, true);
        } catch (IgniteCheckedException ex) {
            commitError(ex);
            errorWhenCommitting();
            // Safe to remove transaction from committed tx list because nothing was committed yet.
            cctx.tm().removeCommittedTx(this);
            throw ex;
        } catch (Throwable ex) {
            commitError(ex);
            errorWhenCommitting();
            // Safe to remove transaction from committed tx list because nothing was committed yet.
            cctx.tm().removeCommittedTx(this);
            if (ex instanceof Error)
                throw (Error) ex;
            throw new IgniteCheckedException("Failed to commit transaction to database: " + this, ex);
        } finally {
            if (isRollbackOnly())
                sessionEnd(stores, false);
        }
    } else
        sessionEnd(stores, true);
}
Also used : CacheLazyEntry(org.apache.ignite.internal.processors.cache.CacheLazyEntry) GridCacheContext(org.apache.ignite.internal.processors.cache.GridCacheContext) IgniteBiTuple(org.apache.ignite.lang.IgniteBiTuple) CacheStoreManager(org.apache.ignite.internal.processors.cache.store.CacheStoreManager) LinkedHashMap(java.util.LinkedHashMap) GridCacheVersion(org.apache.ignite.internal.processors.cache.version.GridCacheVersion) IgniteCheckedException(org.apache.ignite.IgniteCheckedException) CacheObject(org.apache.ignite.internal.processors.cache.CacheObject) KeyCacheObject(org.apache.ignite.internal.processors.cache.KeyCacheObject) CacheObject(org.apache.ignite.internal.processors.cache.CacheObject) KeyCacheObject(org.apache.ignite.internal.processors.cache.KeyCacheObject) GridCacheOperation(org.apache.ignite.internal.processors.cache.GridCacheOperation) KeyCacheObject(org.apache.ignite.internal.processors.cache.KeyCacheObject)

Example 37 with GridCacheVersion

use of org.apache.ignite.internal.processors.cache.version.GridCacheVersion in project ignite by apache.

the class IgniteTxAdapter method commitVersion.

/**
 * @param commitVer Commit version.
 */
@Override
public void commitVersion(GridCacheVersion commitVer) {
    if (commitVer == null)
        return;
    GridCacheVersion commitVer0 = this.commitVer;
    if (commitVer0 != null)
        return;
    synchronized (this) {
        commitVer0 = this.commitVer;
        if (commitVer0 != null)
            return;
        this.commitVer = commitVer;
    }
}
Also used : GridCacheVersion(org.apache.ignite.internal.processors.cache.version.GridCacheVersion)

Example 38 with GridCacheVersion

use of org.apache.ignite.internal.processors.cache.version.GridCacheVersion in project ignite by apache.

the class IgniteTxAdapter method ownsLockUnsafe.

/**
 * {@inheritDoc}
 */
@SuppressWarnings("SimplifiableIfStatement")
@Override
public boolean ownsLockUnsafe(GridCacheEntryEx entry) {
    GridCacheContext cacheCtx = entry.context();
    IgniteTxEntry txEntry = entry(entry.txKey());
    GridCacheVersion explicit = txEntry == null ? null : txEntry.explicitVersion();
    return local() && !cacheCtx.isDht() ? entry.lockedByThreadUnsafe(threadId()) || (explicit != null && entry.lockedByUnsafe(explicit)) : // Otherwise, check if entry is owned by version.
    !entry.hasLockCandidateUnsafe(xidVersion()) || entry.lockedByUnsafe(xidVersion());
}
Also used : GridCacheVersion(org.apache.ignite.internal.processors.cache.version.GridCacheVersion) GridCacheContext(org.apache.ignite.internal.processors.cache.GridCacheContext)

Example 39 with GridCacheVersion

use of org.apache.ignite.internal.processors.cache.version.GridCacheVersion in project ignite by apache.

the class IgniteTxEntry method applyEntryProcessors.

/**
 * @param cacheVal Value.
 * @return New value.
 */
@SuppressWarnings("unchecked")
public CacheObject applyEntryProcessors(CacheObject cacheVal) {
    GridCacheVersion ver;
    try {
        ver = entry.version();
    } catch (GridCacheEntryRemovedException ignore) {
        assert tx == null || tx.optimistic() : tx;
        ver = null;
    }
    Object val = null;
    Object keyVal = null;
    for (T2<EntryProcessor<Object, Object, Object>, Object[]> t : entryProcessors()) {
        try {
            CacheInvokeEntry<Object, Object> invokeEntry = new CacheInvokeEntry(key, keyVal, cacheVal, val, ver, keepBinary(), cached());
            EntryProcessor processor = t.get1();
            processor.process(invokeEntry, t.get2());
            val = invokeEntry.getValue();
            keyVal = invokeEntry.key();
        } catch (Exception ignore) {
        // No-op.
        }
    }
    return ctx.toCacheObject(val);
}
Also used : GridCacheVersion(org.apache.ignite.internal.processors.cache.version.GridCacheVersion) EntryProcessor(javax.cache.processor.EntryProcessor) CacheInvokeEntry(org.apache.ignite.internal.processors.cache.CacheInvokeEntry) GridCacheEntryRemovedException(org.apache.ignite.internal.processors.cache.GridCacheEntryRemovedException) CacheObject(org.apache.ignite.internal.processors.cache.CacheObject) KeyCacheObject(org.apache.ignite.internal.processors.cache.KeyCacheObject) IgniteCheckedException(org.apache.ignite.IgniteCheckedException) GridCacheEntryRemovedException(org.apache.ignite.internal.processors.cache.GridCacheEntryRemovedException)

Example 40 with GridCacheVersion

use of org.apache.ignite.internal.processors.cache.version.GridCacheVersion in project ignite by apache.

the class GridCacheAtomicInvalidPartitionHandlingSelfTest method checkRestarts.

/**
 * @param writeSync Write synchronization mode to check.
 * @throws Exception If failed.
 */
private void checkRestarts(CacheWriteSynchronizationMode writeSync) throws Exception {
    this.writeSync = writeSync;
    final int gridCnt = 6;
    startGrids(gridCnt);
    awaitPartitionMapExchange();
    try {
        assertEquals(testClientNode(), (boolean) grid(0).configuration().isClientMode());
        final IgniteCache<Object, Object> cache = grid(0).cache(DEFAULT_CACHE_NAME);
        final int range = 100_000;
        final Set<Integer> keys = new LinkedHashSet<>();
        try (IgniteDataStreamer<Integer, Integer> streamer = grid(0).dataStreamer(DEFAULT_CACHE_NAME)) {
            streamer.allowOverwrite(true);
            for (int i = 0; i < range; i++) {
                streamer.addData(i, 0);
                keys.add(i);
                if (i > 0 && i % 10_000 == 0)
                    System.err.println("Put: " + i);
            }
        }
        final Affinity<Integer> aff = grid(0).affinity(DEFAULT_CACHE_NAME);
        boolean putDone = GridTestUtils.waitForCondition(new GridAbsPredicate() {

            @Override
            public boolean apply() {
                Iterator<Integer> it = keys.iterator();
                while (it.hasNext()) {
                    Integer key = it.next();
                    Collection<ClusterNode> affNodes = aff.mapKeyToPrimaryAndBackups(key);
                    for (int i = 0; i < gridCnt; i++) {
                        ClusterNode locNode = grid(i).localNode();
                        IgniteCache<Object, Object> cache = grid(i).cache(DEFAULT_CACHE_NAME);
                        Object val = cache.localPeek(key);
                        if (affNodes.contains(locNode)) {
                            if (val == null)
                                return false;
                        } else
                            assertNull(val);
                    }
                    it.remove();
                }
                return true;
            }
        }, 30_000);
        assertTrue(putDone);
        assertTrue(keys.isEmpty());
        final AtomicBoolean done = new AtomicBoolean();
        delay = true;
        System.err.println("FINISHED PUTS");
        // Start put threads.
        IgniteInternalFuture<?> fut = multithreadedAsync(new Callable<Object>() {

            @Override
            public Object call() throws Exception {
                Random rnd = new Random();
                while (!done.get()) {
                    try {
                        int cnt = rnd.nextInt(5);
                        if (cnt < 2) {
                            int key = rnd.nextInt(range);
                            int val = rnd.nextInt();
                            cache.put(key, val);
                        } else {
                            Map<Integer, Integer> upd = new TreeMap<>();
                            for (int i = 0; i < cnt; i++) upd.put(rnd.nextInt(range), rnd.nextInt());
                            cache.putAll(upd);
                        }
                    } catch (CachePartialUpdateException ignored) {
                    // No-op.
                    }
                }
                return null;
            }
        }, 4, "putAll-thread");
        Random rnd = new Random();
        // Restart random nodes.
        for (int r = 0; r < 20; r++) {
            int idx0 = rnd.nextInt(gridCnt - 1) + 1;
            stopGrid(idx0);
            U.sleep(200);
            startGrid(idx0);
        }
        done.set(true);
        awaitPartitionMapExchange();
        fut.get();
        for (int k = 0; k < range; k++) {
            Collection<ClusterNode> affNodes = affinity(cache).mapKeyToPrimaryAndBackups(k);
            // Test is valid with at least one backup.
            assert affNodes.size() >= 2;
            Object val = null;
            GridCacheVersion ver = null;
            UUID nodeId = null;
            for (int i = 0; i < gridCnt; i++) {
                ClusterNode locNode = grid(i).localNode();
                GridCacheAdapter<Object, Object> c = ((IgniteKernal) grid(i)).internalCache(DEFAULT_CACHE_NAME);
                GridCacheEntryEx entry = null;
                try {
                    entry = c.entryEx(k);
                    entry.unswap();
                } catch (GridDhtInvalidPartitionException ignored) {
                // Skip key.
                }
                for (int r = 0; r < 10; r++) {
                    try {
                        if (affNodes.contains(locNode)) {
                            assert c.affinity().isPrimaryOrBackup(locNode, k);
                            boolean primary = c.affinity().isPrimary(locNode, k);
                            assertNotNull("Failed to find entry on node for key [locNode=" + locNode.id() + ", key=" + k + ']', entry);
                            if (val == null) {
                                assertNull(ver);
                                val = CU.value(entry.rawGet(), entry.context(), false);
                                ver = entry.version();
                                nodeId = locNode.id();
                            } else {
                                assertNotNull(ver);
                                assertEquals("Failed to check value for key [key=" + k + ", node=" + locNode.id() + ", primary=" + primary + ", recNodeId=" + nodeId + ']', val, CU.value(entry.rawGet(), entry.context(), false));
                                assertEquals("Failed to check version for key [key=" + k + ", node=" + locNode.id() + ", primary=" + primary + ", recNodeId=" + nodeId + ']', ver, entry.version());
                            }
                        } else
                            assertTrue("Invalid entry: " + entry, entry == null || !entry.partitionValid());
                    } catch (AssertionError e) {
                        if (r == 9) {
                            info("Failed to verify cache contents: " + e.getMessage());
                            throw e;
                        }
                        info("Failed to verify cache contents, will retry: " + e.getMessage());
                        // Give some time to finish async updates.
                        U.sleep(1000);
                    }
                }
            }
        }
    } finally {
        stopAllGrids();
    }
}
Also used : LinkedHashSet(java.util.LinkedHashSet) GridCacheVersion(org.apache.ignite.internal.processors.cache.version.GridCacheVersion) Random(java.util.Random) Iterator(java.util.Iterator) UUID(java.util.UUID) ClusterNode(org.apache.ignite.cluster.ClusterNode) IgniteKernal(org.apache.ignite.internal.IgniteKernal) GridDhtInvalidPartitionException(org.apache.ignite.internal.processors.cache.distributed.dht.GridDhtInvalidPartitionException) GridAbsPredicate(org.apache.ignite.internal.util.lang.GridAbsPredicate) IgniteCache(org.apache.ignite.IgniteCache) CachePartialUpdateException(org.apache.ignite.cache.CachePartialUpdateException) CachePartialUpdateException(org.apache.ignite.cache.CachePartialUpdateException) GridDhtInvalidPartitionException(org.apache.ignite.internal.processors.cache.distributed.dht.GridDhtInvalidPartitionException) AtomicBoolean(java.util.concurrent.atomic.AtomicBoolean) GridCacheEntryEx(org.apache.ignite.internal.processors.cache.GridCacheEntryEx) Collection(java.util.Collection) Map(java.util.Map) TreeMap(java.util.TreeMap)

Aggregations

GridCacheVersion (org.apache.ignite.internal.processors.cache.version.GridCacheVersion)198 IgniteCheckedException (org.apache.ignite.IgniteCheckedException)59 UUID (java.util.UUID)57 KeyCacheObject (org.apache.ignite.internal.processors.cache.KeyCacheObject)55 CacheObject (org.apache.ignite.internal.processors.cache.CacheObject)47 GridCacheEntryRemovedException (org.apache.ignite.internal.processors.cache.GridCacheEntryRemovedException)42 GridCacheEntryEx (org.apache.ignite.internal.processors.cache.GridCacheEntryEx)23 ClusterNode (org.apache.ignite.cluster.ClusterNode)20 AffinityTopologyVersion (org.apache.ignite.internal.processors.affinity.AffinityTopologyVersion)20 Map (java.util.Map)18 ClusterTopologyCheckedException (org.apache.ignite.internal.cluster.ClusterTopologyCheckedException)17 ArrayList (java.util.ArrayList)16 IgniteInternalFuture (org.apache.ignite.internal.IgniteInternalFuture)15 GridCacheMvccCandidate (org.apache.ignite.internal.processors.cache.GridCacheMvccCandidate)14 GridDhtInvalidPartitionException (org.apache.ignite.internal.processors.cache.distributed.dht.GridDhtInvalidPartitionException)14 IgniteTxEntry (org.apache.ignite.internal.processors.cache.transactions.IgniteTxEntry)14 IgniteTxKey (org.apache.ignite.internal.processors.cache.transactions.IgniteTxKey)14 GridCacheContext (org.apache.ignite.internal.processors.cache.GridCacheContext)13 Nullable (org.jetbrains.annotations.Nullable)13 GridCacheOperation (org.apache.ignite.internal.processors.cache.GridCacheOperation)12