/// <summary> /// Do not return an item whose timestamp is later than the current /// transaction timestamp. (Otherwise we might compromise repeatable /// read unnecessarily.) Do not return an item which is soft-locked. /// Always go straight to the database instead. /// </summary> /// <remarks> /// Note that since reading an item from that cache does not actually /// go to the database, it is possible to see a kind of phantom read /// due to the underlying row being updated after we have read it /// from the cache. This would not be possible in a lock-based /// implementation of repeatable read isolation. It is also possible /// to overwrite changes made and committed by another transaction /// after the current transaction read the item from the cache. This /// problem would be caught by the update-time version-checking, if /// the data is versioned or timestamped. /// </remarks> public async Task <object> GetAsync(CacheKey key, long txTimestamp, CancellationToken cancellationToken) { cancellationToken.ThrowIfCancellationRequested(); using (await _lockObjectAsync.LockAsync()) { if (log.IsDebugEnabled()) { log.Debug("Cache lookup: {0}", key); } // commented out in H3.1 /*try * { * cache.Lock( key );*/ ILockable lockable = (ILockable)await(cache.GetAsync(key, cancellationToken)).ConfigureAwait(false); bool gettable = lockable != null && lockable.IsGettable(txTimestamp); if (gettable) { if (log.IsDebugEnabled()) { log.Debug("Cache hit: {0}", key); } return(((CachedItem)lockable).Value); } else { if (log.IsDebugEnabled()) { if (lockable == null) { log.Debug("Cache miss: {0}", key); } else { log.Debug("Cached item was locked: {0}", key); } } return(null); } /*} * finally * { * cache.Unlock( key ); * }*/ } }
/// <summary> /// Do not return an item whose timestamp is later than the current /// transaction timestamp. (Otherwise we might compromise repeatable /// read unnecessarily.) Do not return an item which is soft-locked. /// Always go straight to the database instead. /// </summary> /// <remarks> /// Note that since reading an item from that cache does not actually /// go to the database, it is possible to see a kind of phantom read /// due to the underlying row being updated after we have read it /// from the cache. This would not be possible in a lock-based /// implementation of repeatable read isolation. It is also possible /// to overwrite changes made and committed by another transaction /// after the current transaction read the item from the cache. This /// problem would be caught by the update-time version-checking, if /// the data is versioned or timestamped. /// </remarks> public object Get(CacheKey key, long txTimestamp) { lock (_lockObject) { if (log.IsDebugEnabled()) { log.Debug("Cache lookup: {0}", key); } // commented out in H3.1 /*try * { * cache.Lock( key );*/ ILockable lockable = (ILockable)cache.Get(key); bool gettable = lockable != null && lockable.IsGettable(txTimestamp); if (gettable) { if (log.IsDebugEnabled()) { log.Debug("Cache hit: {0}", key); } return(((CachedItem)lockable).Value); } else { if (log.IsDebugEnabled()) { if (lockable == null) { log.Debug("Cache miss: {0}", key); } else { log.Debug("Cached item was locked: {0}", key); } } return(null); } /*} * finally * { * cache.Unlock( key ); * }*/ } }
/// <summary> /// Do not return an item whose timestamp is later than the current /// transaction timestamp. (Otherwise we might compromise repeatable /// read unnecessarily.) Do not return an item which is soft-locked. /// Always go straight to the database instead. /// </summary> /// <remarks> /// Note that since reading an item from that cache does not actually /// go to the database, it is possible to see a kind of phantom read /// due to the underlying row being updated after we have read it /// from the cache. This would not be possible in a lock-based /// implementation of repeatable read isolation. It is also possible /// to overwrite changes made and committed by another transaction /// after the current transaction read the item from the cache. This /// problem would be caught by the update-time version-checking, if /// the data is versioned or timestamped. /// </remarks> /// <param name="key"></param> /// <param name="txTimestamp"></param> /// <returns></returns> public object Get(object key, long txTimestamp) { lock ( _lockObject ) { if (log.IsDebugEnabled) { log.Debug("Cache lookup: " + key); } try { cache.Lock(key); ILockable lockable = ( ILockable )cache.Get(key); bool gettable = lockable != null && lockable.IsGettable(txTimestamp); if (gettable) { if (log.IsDebugEnabled) { log.Debug("Cache hit: " + key); } return((( CachedItem )lockable).Value); } else { if (log.IsDebugEnabled) { if (lockable == null) { log.Debug("Cache miss: " + key); } else { log.Debug("Cached item was locked: " + key); } } return(null); } } finally { cache.Unlock(key); } } }