/** {@inheritDoc} */ @Override public boolean mvccEnabled() { GridCacheContext ctx0 = cacheCtx; return ctx0 != null && ctx0.mvccEnabled(); }
/** {@inheritDoc} */ @Override public boolean isMvcc() { return cctx.mvccEnabled(); }
/** * Throw an {@link UnsupportedOperationException} if this cache is transactional and MVCC is enabled with * appropriate message about corresponding operation type. * @param cctx Cache context. * @param opType operation type to mention in error message. */ public static void verifyMvccOperationSupport(GridCacheContext<?, ?> cctx, String opType) { if (cctx.mvccEnabled()) throw new UnsupportedOperationException(opType + " operations are not supported on transactional " + "caches when MVCC is enabled."); }
/** {@inheritDoc} */ @Override public boolean mvccEnabled() { for (IgniteTxEntry e : writeMap.values()) { if (e.context().mvccEnabled()) return true; } return false; } }
/** {@inheritDoc} */ @Override public boolean mvccEnabled() { return entry != null && entry.context().mvccEnabled(); } }
/** * Checks if it is possible to directly read data memory without entry creation (this * is optimization to avoid unnecessary blocking synchronization on cache entry). * * @param expiryPlc Optional expiry policy for read operation. * @param readers {@code True} if need update near cache readers. * @return {@code True} if it is possible to directly read offheap instead of using {@link GridCacheEntryEx#innerGet}. */ public boolean readNoEntry(@Nullable IgniteCacheExpiryPolicy expiryPlc, boolean readers) { return mvccEnabled() || (!config().isOnheapCacheEnabled() && !readers && expiryPlc == null); }
/** {@inheritDoc} */ @Override protected BPlusTree.TreeRowClosure<GridH2SearchRow, GridH2Row> filter(GridH2QueryContext qctx) { if (qctx == null) { assert !cctx.mvccEnabled(); return null; } IndexingQueryFilter f = qctx.filter(); IndexingQueryCacheFilter p = f == null ? null : f.forCache(getTable().cacheName()); MvccSnapshot v = qctx.mvccSnapshot(); assert !cctx.mvccEnabled() || v != null; if(p == null && v == null) return null; return new H2TreeFilterClosure(p, v, cctx, log); }
/** * Initialises MVCC filter and returns MVCC query tracker if needed. * @param cctx Cache context. * @param startTx Start transaction flag. * @return MVCC query tracker. * @throws IgniteCheckedException If failed. */ @NotNull public static MvccQueryTracker mvccTracker(GridCacheContext cctx, boolean startTx) throws IgniteCheckedException { assert cctx != null && cctx.mvccEnabled(); GridNearTxLocal tx = tx(cctx.kernalContext()); if (tx == null && startTx) tx = txStart(cctx, 0); return mvccTracker(cctx, tx); }
/** * @param cacheCtx Cache context. * @param retval Return value flag. * @param mvccOp SQL operation flag. * @throws IgniteCheckedException If failed. */ private void beforeRemove(GridCacheContext cacheCtx, boolean retval, boolean mvccOp) throws IgniteCheckedException { assert !mvccOp || cacheCtx.mvccEnabled(); checkUpdatesAllowed(cacheCtx); cacheCtx.checkSecurity(SecurityPermission.CACHE_REMOVE); if (cacheCtx.mvccEnabled() && !isOperationAllowed(mvccOp)) throw new IgniteCheckedException(TX_TYPE_MISMATCH_ERR_MSG); if (retval) needReturnValue(true); checkValid(); }
/** * @param cacheCtx Cache context. * @param retval Return value flag. * @param mvccOp SQL operation flag. * @throws IgniteCheckedException If failed. */ private void beforePut(GridCacheContext cacheCtx, boolean retval, boolean mvccOp) throws IgniteCheckedException { assert !mvccOp || cacheCtx.mvccEnabled(); checkUpdatesAllowed(cacheCtx); cacheCtx.checkSecurity(SecurityPermission.CACHE_PUT); if (cacheCtx.mvccEnabled() && !isOperationAllowed(mvccOp)) throw new IgniteCheckedException(TX_TYPE_MISMATCH_ERR_MSG); if (retval) needReturnValue(true); checkValid(); init(); }
/** * * @param key Key. * @param part Partition. * @param topVer Topology version. * @param affNodes Affynity nodes. */ private boolean tryLocalGet( KeyCacheObject key, int part, AffinityTopologyVersion topVer, List<ClusterNode> affNodes ) { // Local get cannot be used with MVCC as local node can contain some visible version which is not latest. boolean fastLocGet = !cctx.mvccEnabled() && (!forcePrimary || affNodes.get(0).isLocal()) && cctx.reserveForFastLocalGet(part, topVer); if (fastLocGet) { try { if (localGet(topVer, key, part)) return true; } finally { cctx.releaseForFastLocalGet(part, topVer); } } return false; }
/** * TODO: IGNITE-3500: do we need to generate event and invalidate value? * * @return {@code true} if expired. * @throws IgniteCheckedException In case of failure. */ private boolean checkExpired() throws IgniteCheckedException { assert lock.isHeldByCurrentThread(); long expireTime = expireTimeExtras(); if (expireTime > 0) { long delta = expireTime - U.currentTimeMillis(); if (delta <= 0) { if (cctx.mvccEnabled()) cctx.offheap().mvccRemoveAll(this); else removeValue(); return true; } } return false; }
/** */ protected GridNearTxLocal checkCurrentTx() { if (!ctx.mvccEnabled()) return ctx.tm().threadLocalTx(ctx); try { return MvccUtils.currentTx(ctx.kernalContext(), null); } catch (MvccUtils.UnsupportedTxModeException | MvccUtils.NonMvccTransactionException e) { throw new TransactionException(e.getMessage()); } }
/** * Retrieves all versions of all keys from cache. * * @param cache Cache. * @return {@link Map} of keys to its versions. * @throws IgniteCheckedException If failed. */ private Map<KeyCacheObject, List<CacheDataRow>> allVersions(IgniteCache cache) throws IgniteCheckedException { IgniteCacheProxy cache0 = (IgniteCacheProxy)cache; GridCacheContext cctx = cache0.context(); assert cctx.mvccEnabled(); Map<KeyCacheObject, List<CacheDataRow>> vers = new HashMap<>(); for (Object e : cache) { IgniteBiTuple entry = (IgniteBiTuple)e; KeyCacheObject key = cctx.toCacheKeyObject(entry.getKey()); GridCursor<CacheDataRow> cur = cctx.offheap().mvccAllVersionsCursor(cctx, key, null); List<CacheDataRow> rows = new ArrayList<>(); while (cur.next()) { CacheDataRow row = cur.get(); rows.add(row); } vers.put(key, rows); } return vers; }
/** * Check if query may be run locally on all caches mentioned in the query. * * @return {@code true} if query may be run locally on all caches mentioned in the query, i.e. there's no need * to run distributed query. */ public boolean isLocalQuery() { if (selectForUpdate) return false; for (Object o : h2ObjToGridObj.values()) { if (o instanceof GridSqlAlias) o = GridSqlAlias.unwrap((GridSqlAst)o); if (o instanceof GridSqlTable) { GridH2Table tbl = ((GridSqlTable)o).dataTable(); if (tbl != null) { //It's not affinity cache. Can't be local. if (tbl.cacheContext() == null) return false; GridCacheContext cctx = tbl.cacheContext(); if (cctx.mvccEnabled()) return false; if (cctx.isPartitioned()) return false; if (cctx.isReplicated() && !cctx.isReplicatedAffinityNode()) return false; } } } return true; }
/** * @param cache Cache. */ private void testInvoke(final IgniteCache<Object, Object> cache) throws Exception { Class<? extends Exception> exp = grid("client").transactions().tx() == null || ((IgniteCacheProxy)cache).context().mvccEnabled() ? EntryProcessorException.class : NonSerializableException.class; //noinspection ThrowableNotThrown assertThrows(log, new Callable<Object>() { @Override public Object call() throws Exception { cache.invoke("1", new UpdateProcessor()); return null; } }, exp, null); if (ATOMIC_CACHE.equals(cache.getName())) { //noinspection ThrowableNotThrown assertThrows(log, new Callable<Object>() { @Override public Object call() throws Exception { cache.invoke("1", new UpdateValueProcessor()); return null; } }, CachePartialUpdateException.class, null); } }
/** {@inheritDoc} */ @Override public Cursor find(Session ses, SearchRow lower, SearchRow upper) { assert lower == null || lower instanceof GridH2SearchRow : lower; assert upper == null || upper instanceof GridH2SearchRow : upper; try { int seg = threadLocalSegment(); H2Tree tree = treeForRead(seg); if (!cctx.mvccEnabled() && indexType.isPrimaryKey() && lower != null && upper != null && tree.compareRows((GridH2SearchRow)lower, (GridH2SearchRow)upper) == 0) { GridH2Row row = tree.findOne((GridH2SearchRow)lower, filter(GridH2QueryContext.get()), null); return (row == null) ? GridH2Cursor.EMPTY : new SingleRowCursor(row); } else { return new H2Cursor(tree.find((GridH2SearchRow)lower, (GridH2SearchRow)upper, filter(GridH2QueryContext.get()), null)); } } catch (IgniteCheckedException e) { throw DbException.convert(e); } }
/** */ private void checkAllVersionsHints(IgniteCache cache) throws IgniteCheckedException { IgniteCacheProxy cache0 = (IgniteCacheProxy)cache; GridCacheContext cctx = cache0.context(); assert cctx.mvccEnabled(); for (Object e : cache) { IgniteBiTuple entry = (IgniteBiTuple)e; KeyCacheObject key = cctx.toCacheKeyObject(entry.getKey()); GridCursor<CacheDataRow> cur = cctx.offheap().mvccAllVersionsCursor(cctx, key, CacheDataRowAdapter.RowData.LINK_WITH_HEADER); while (cur.next()) { CacheDataRow row = cur.get(); assertTrue(row.mvccTxState() != 0); } } }
/** * Handle of cache context which was fully prepared. * * @param cacheCtx Fully prepared context. * @throws IgniteCheckedException if failed. */ private void onCacheStarted(GridCacheContext cacheCtx) throws IgniteCheckedException { GridCacheAdapter cache = cacheCtx.cache(); CacheConfiguration cfg = cacheCtx.config(); CacheGroupContext grp = cacheGrps.get(cacheCtx.groupId()); cacheCtx.onStarted(); String dataRegion = cfg.getDataRegionName(); if (dataRegion == null && ctx.config().getDataStorageConfiguration() != null) dataRegion = ctx.config().getDataStorageConfiguration().getDefaultDataRegionConfiguration().getName(); if (log.isInfoEnabled()) { log.info("Started cache [name=" + cfg.getName() + ", id=" + cacheCtx.cacheId() + (cfg.getGroupName() != null ? ", group=" + cfg.getGroupName() : "") + ", dataRegionName=" + dataRegion + ", mode=" + cfg.getCacheMode() + ", atomicity=" + cfg.getAtomicityMode() + ", backups=" + cfg.getBackups() + ", mvcc=" + cacheCtx.mvccEnabled() + ']'); } grp.onCacheStarted(cacheCtx); onKernalStart(cache); }
/** * Checks update counter value on all nodes. * * @param cacheName Cache name. * @param p Part number. * @param val Expected partition counter value. */ private void checkUpdateCounters(String cacheName, int p, long val) { for (Ignite node : G.allGrids()) { if (!node.configuration().isClientMode()) { IgniteCacheProxy cache = (IgniteCacheProxy)node.cache(cacheName); GridDhtLocalPartition part = cache.context().topology().localPartition(p); if (!cache.context().mvccEnabled() || part == null) continue; assertEquals("part=" + p, val, part.updateCounter()); } } } }