Exemple #1
0
        public void Set(string key, object data, TimeSpan cacheTime)
        {
            DataCacheLockHandle handle = null;

            handle = RetryHelper.Execute(
                () =>
            {
                DataCacheLockHandle innerHandle = null;
                var output = _cache.GetAndLock(key, TimeSpan.FromSeconds(240), out innerHandle);
                return(innerHandle);
            }, (ex) => true, 50, false, 50);
            DataCacheItemVersion version = null;

            if (handle == null)
            {
                version = _cache.Put(key, data, cacheTime);
            }
            else
            {
                version = _cache.PutAndUnlock(key, data, handle, cacheTime);
            }
            OnObjectPut(new ObjectPutEventArgs()
            {
                Key = key, Version = version
            });
        }
Exemple #2
0
        /// <summary>
        /// Attempts to lock the key in the locks region and stores a reference to the lock handle in memory.
        /// If the lock region doesn't exists, it will attempt to create it.
        /// </summary>
        /// <param name="key">The key to lock.</param>
        /// <param name="createMissingRegion">A flag to determine whether or not to create the lock region if it doesn't
        /// exist.</param>
        private void Lock(object key, bool createMissingRegion)
        {
            DataCacheLockHandle lockHandle = null;

            try
            {
                _locksCache.GetAndLock(key.ToString(), TimeSpan.FromMilliseconds(Timeout), out lockHandle, LocksRegionName, true);

                lock (_lockHandles)
                {
                    _lockHandles.Add(key.ToString(), lockHandle);
                }
            }
            catch (DataCacheException ex)
            {
                if (ex.ErrorCode == DataCacheErrorCode.RegionDoesNotExist && createMissingRegion)
                {
                    CreateLocksRegion(b => Lock(key, false));
                }
                else
                {
                    throw new CacheException(ex);
                }
            }
        }
Exemple #3
0
 public void Remove(string key)
 {
     try
     {
         DataCacheLockHandle handle = null;
         handle = RetryHelper.Execute(
             () =>
         {
             DataCacheLockHandle innerHandle = null;
             var output = _cache.GetAndLock(key, TimeSpan.FromSeconds(30), out innerHandle);
             return(innerHandle);
         }, (ex) => true, 50, false, 50);
         if (handle != null)
         {
             _cache.Remove(key, handle);
             //_cache.Unlock(key, handle);
         }
     }
     catch (DataCacheException ex)
     {
         if (ex.ErrorCode != DataCacheErrorCode.KeyDoesNotExist)
         {
             EventLog.WriteEntry("Application", ex.ToString(), EventLogEntryType.Error);
         }
     }
 }
        /// <summary>
        /// 锁
        /// </summary>
        /// <param name="key"></param>
        /// <returns></returns>
        public override bool LockCache(string key, int timeout)
        {
            var cachekey   = key;
            var lockobject = Get(cachekey);

            if (lockobject == null)
            {
                Insert(cachekey, false);
            }

            DataCacheLockHandle lockHandle = null;

            try
            {
                GetAppfabricCache();
                Insert(cachekey, true);
                lockobject = _memCache.GetAndLock(cachekey, TimeSpan.FromMinutes(timeout), out lockHandle);
            }
            catch//异常为此缓存已被加锁
            {
                return(false);
            }

            if (_lockHandles.ContainsKey(key))
            {
                _lockHandles.Remove(key);
            }
            _lockHandles.Add(key, lockHandle);
            return(true);
        }
        public override bool Obtain()
        {
            bool hasLock = _lockHandle != null;

            if (!hasLock)
            {
                try
                {
                    _persistantCache.GetAndLock(_lockName, TimeSpan.FromSeconds(30), out _lockHandle, _cacheRegion, true);
                    hasLock = true;
                }
                catch (DataCacheException ex)
                {
                    if (ex.ErrorCode == (int)DataCacheErrorCode.KeyDoesNotExist)
                    {
                        // Put is not effected by locks
                        _persistantCache.Put(_lockName, true, _cacheRegion);
                        hasLock = true;
                    }
                    else if (ex.ErrorCode == (int)DataCacheErrorCode.ObjectLocked)
                    {
                        // make sure out lock handle isn't set
                        _lockHandle = null;
                    }
                }
            }

            return hasLock;
        }
Exemple #6
0
        /// <summary>
        /// Unlocks the specified name.
        /// </summary>
        /// <param name="name">The name.</param>
        /// <param name="lockHandle">The lock handle.</param>
        /// <param name="timeout">The timeout.</param>
        public void Unlock(string name, DataCacheLockHandle lockHandle, TimeSpan timeout)
        {
            string region;

            if (!Settings.TryGetRegion(ref name, out region))
            {
                Cache.Unlock(name, lockHandle, timeout);
            }
            else
            {
                Cache.Unlock(name, lockHandle, timeout);
            }
        }
        public override void Release()
        {
            if (_lockHandle != null)
            {
                _persistantCache.PutAndUnlock(_lockName, false, _lockHandle, _cacheRegion);
                _lockHandle = null;

                // Try to get rid of the lock entirely
                try
                {
                    _persistantCache.Remove(_lockName, _cacheRegion);
                }
                catch { /* Eat the exception here */ }
            }
        }
Exemple #8
0
        public T Get <T>(string key, out IConcurrencyHandle handle) where T : new()
        {
            var retryPolicy = new LockRetryPolicy();
            DataCacheLockHandle lockHandle = null;
            object item = null;

            HandleBadDataCacheBug(() => retryPolicy.Handle(() =>
            {
                item = _dataCache.GetAndLock(key, TimeSpan.FromSeconds(1), out lockHandle, true);
            }));

            handle = new AzureLockHandle
            {
                Instance = lockHandle
            };
            return((T)item);
        }
 /// <summary>
 /// Unlocks the specified name.
 /// </summary>
 /// <param name="name">The name.</param>
 /// <param name="lockHandle">The lock handle.</param>
 /// <param name="timeout">The timeout.</param>
 public void Unlock(string name, DataCacheLockHandle lockHandle, TimeSpan timeout)
 {
     string region;
     if (!Settings.TryGetRegion(ref name, out region)) Cache.Unlock(name, lockHandle, timeout);
     else Cache.Unlock(name, lockHandle, timeout);
 }
 /// <summary>
 /// Gets the and lock.
 /// </summary>
 /// <param name="name">The name.</param>
 /// <param name="timeout">The timeout.</param>
 /// <param name="lockHandle">The lock handle.</param>
 /// <param name="forceLock">if set to <c>true</c> [force lock].</param>
 /// <returns></returns>
 public object GetAndLock(string name, TimeSpan timeout, out DataCacheLockHandle lockHandle, bool forceLock)
 {
     string region;
     return (!Settings.TryGetRegion(ref name, out region) ? Cache.GetAndLock(name, timeout, out lockHandle, forceLock) : Cache.GetAndLock(name, timeout, out lockHandle, region, forceLock));
 }
Exemple #11
0
        /// <summary>
        /// Gets the and lock.
        /// </summary>
        /// <param name="name">The name.</param>
        /// <param name="timeout">The timeout.</param>
        /// <param name="lockHandle">The lock handle.</param>
        /// <param name="forceLock">if set to <c>true</c> [force lock].</param>
        /// <returns></returns>
        public object GetAndLock(string name, TimeSpan timeout, out DataCacheLockHandle lockHandle, bool forceLock)
        {
            string region;

            return(!Settings.TryGetRegion(ref name, out region) ? Cache.GetAndLock(name, timeout, out lockHandle, forceLock) : Cache.GetAndLock(name, timeout, out lockHandle, region, forceLock));
        }
Exemple #12
0
        /// <summary>
        /// Updates an existing key in the cache.
        /// <para>
        /// The cache manager will make sure the update will always happen on the most recent version.
        /// </para>
        /// <para>
        /// If version conflicts occur, if for example multiple cache clients try to write the same
        /// key, and during the update process, someone else changed the value for the key, the
        /// cache manager will retry the operation.
        /// </para>
        /// <para>
        /// The <paramref name="updateValue"/> function will get invoked on each retry with the most
        /// recent value which is stored in cache.
        /// </para>
        /// </summary>
        /// <param name="key">The key to update.</param>
        /// <param name="region">The cache region.</param>
        /// <param name="updateValue">The function to perform the update.</param>
        /// <param name="config">The cache configuration used to specify the update behavior.</param>
        /// <returns>The update result which is interpreted by the cache manager.</returns>
        /// <exception cref="System.ArgumentNullException">If updateValue or config are null.</exception>
        /// <remarks>
        /// If the cache does not use a distributed cache system. Update is doing exactly the same
        /// as Get plus Put.
        /// </remarks>
        public override UpdateItemResult <TCacheValue> Update(string key, string region, Func <TCacheValue, TCacheValue> updateValue, UpdateItemConfig config)
        {
            if (updateValue == null)
            {
                throw new ArgumentNullException("updateValue");
            }
            if (config == null)
            {
                throw new ArgumentNullException("config");
            }

            DataCacheLockHandle     lockHandle = null;
            CacheItem <TCacheValue> item       = null;
            var retry = false;  // indicate lock = version conflict
            var hasVersionConflict = false;
            var tries = 0;

            do
            {
                tries++;
                retry = false;
                try
                {
                    if (string.IsNullOrWhiteSpace(region))
                    {
                        item = this.cache.GetAndLock(key, TimeSpan.FromMilliseconds(100), out lockHandle) as CacheItem <TCacheValue>;
                    }
                    else
                    {
                        RegisterRegion(region);
                        item = this.cache.GetAndLock(key, TimeSpan.FromMilliseconds(100), out lockHandle, region) as CacheItem <TCacheValue>;
                    }
                }
                catch (DataCacheException ex)
                {
                    if (ex.ErrorCode == DataCacheErrorCode.ObjectLocked)
                    {
                        // object seems to be locked so we have a version conflict and we'll retry...
                        retry = true;
                        hasVersionConflict = true;
                    }
                    else if (IsTransientError(ex))
                    {
                        retry = true;
                        Task.Delay(DefaultRetryWaitTimeout).Wait();
                    }
                    else
                    {
                        throw;
                    }
                }
            }while (retry && tries <= config.MaxRetries);

            if (item == null)
            {
                return(new UpdateItemResult <TCacheValue>(default(TCacheValue), hasVersionConflict, false, tries));
            }

            do
            {
                // fix: never actually updated the item next retry...
                item = item.WithValue(updateValue(item.Value));

                tries++;
                retry = false;
                try
                {
                    if (string.IsNullOrWhiteSpace(item.Region))
                    {
                        if (item.ExpirationTimeout != TimeSpan.Zero)
                        {
                            this.cache.PutAndUnlock(item.Key, item, lockHandle, item.ExpirationTimeout);
                        }
                        else
                        {
                            this.cache.PutAndUnlock(item.Key, item, lockHandle);
                        }
                    }
                    else
                    {
                        if (item.ExpirationTimeout != TimeSpan.Zero)
                        {
                            this.cache.PutAndUnlock(item.Key, item, lockHandle, item.ExpirationTimeout, item.Region);
                        }
                        else
                        {
                            this.cache.PutAndUnlock(item.Key, item, lockHandle, item.Region);
                        }
                    }

                    return(new UpdateItemResult <TCacheValue>(item.Value, hasVersionConflict, true, tries));
                }
                catch (DataCacheException ex)
                {
                    if (ex.ErrorCode == DataCacheErrorCode.ObjectNotLocked ||
                        ex.ErrorCode == DataCacheErrorCode.InvalidCacheLockHandle ||
                        ex.ErrorCode == DataCacheErrorCode.KeyDoesNotExist)
                    {
                        return(new UpdateItemResult <TCacheValue>(default(TCacheValue), hasVersionConflict, false, tries));
                    }
                    else if (IsTransientError(ex))
                    {
                        Task.Delay(DefaultRetryWaitTimeout).Wait();
                        retry = true;
                    }
                    else
                    {
                        // return new UpdateItemResult(hasVersionConflict, false, tries);
                        throw; // shell we throw the exception? Usually we just return false...
                    }
                }
            }while (retry && tries <= config.MaxRetries);

            return(new UpdateItemResult <TCacheValue>(default(TCacheValue), hasVersionConflict, false, tries));
        }