/** * The keys returned are a union of the set of keys in the current transaction and those in the * backing cache. */ @SuppressWarnings({"unchecked", "rawtypes"}) public Collection<K> getKeys() { Collection<Serializable> keys = null; // in-txn layering if (AlfrescoTransactionSupport.getTransactionId() != null) { keys = new HashSet<Serializable>(23); TransactionData txnData = getTransactionData(); if (!txnData.isClearOn) { // the backing cache is not due for a clear Collection<K> backingKeys = (Collection<K>) sharedCache.getKeys(); Collection<Serializable> backingCacheKeys = new HashSet<Serializable>(backingKeys.size()); for (K backingKey : backingKeys) { backingCacheKeys.add(getTenantAwareCacheKey(backingKey)); } keys.addAll(backingCacheKeys); } // add keys keys.addAll(txnData.updatedItemsCache.keySet()); // remove keys keys.removeAll(txnData.removedItemsCache); } else { // no transaction, so just use the backing cache keys = (Collection) sharedCache.getKeys(); } Collection<K> cacheKeys = new HashSet<K>(keys.size()); String currentCacheRegion = TenantUtil.getCurrentDomain(); for (Serializable key : keys) { if (key instanceof CacheRegionKey) { CacheRegionKey cacheRegionKey = (CacheRegionKey) key; if (currentCacheRegion.equals(cacheRegionKey.getCacheRegion())) { cacheKeys.add((K) cacheRegionKey.getCacheKey()); } } else { cacheKeys.add((K) key); } } // done return cacheKeys; }
/** * Transaction-long setting to force all the share cache to be bypassed for the current * transaction. * * <p>This setting is like having a {@link NullCache null} {@link #setSharedCache(SimpleCache) * shared cache}, but only lasts for the transaction. * * <p>Use this when a read transaction <b>must</b> see consistent and current data i.e. go to the * database. While this is active, write operations will also not be committed to the shared * cache. * * @param noSharedCacheRead <tt>true</tt> to avoid reading from the shared cache for the * transaction */ @SuppressWarnings("unchecked") public void setDisableSharedCacheReadForTransaction(boolean noSharedCacheRead) { TransactionData txnData = getTransactionData(); // If we are switching on noSharedCacheRead mode, convert all existing reads and updates to // avoid 'consistent // read' behaviour giving us a potentially out of date node already accessed if (noSharedCacheRead && !txnData.noSharedCacheRead) { txnData.noSharedCacheRead = noSharedCacheRead; String currentCacheRegion = TenantUtil.getCurrentDomain(); for (Map.Entry<Serializable, CacheBucket<V>> entry : new ArrayList<Map.Entry<Serializable, CacheBucket<V>>>( txnData.updatedItemsCache.entrySet())) { Serializable cacheKey = entry.getKey(); K key = null; if (cacheKey instanceof CacheRegionKey) { CacheRegionKey cacheRegionKey = (CacheRegionKey) cacheKey; if (currentCacheRegion.equals(cacheRegionKey.getCacheRegion())) { key = (K) cacheRegionKey.getCacheKey(); } } else { key = (K) cacheKey; } if (key != null) { CacheBucket<V> bucket = entry.getValue(); // Simply 'forget' reads if (bucket instanceof ReadCacheBucket) { txnData.updatedItemsCache.remove(cacheKey); } // Convert updates to removes else if (bucket instanceof UpdateCacheBucket) { remove(key); } // Leave new entries alone - they can't have come from the shared cache } } } }