Мы видели эту проблему и в нашем коде. Мы решаем эту проблему, перегружая метод Get, чтобы перехватить ожидания, а затем повторить вызов N раз, прежде чем перейти к прямому запросу к SQL.
Вот код, который мы используем для получения данных из кеша
private static bool TryGetFromCache(string cacheKey, string region, out GetMappingValuesToCacheResult cacheResult, int counter = 0)
{
cacheResult = new GetMappingValuesToCacheResult();
try
{
// use as instead of cast, as this will return null instead of exception caused by casting.
if (_cache == null) return false;
cacheResult = _cache.Get(cacheKey, region) as GetMappingValuesToCacheResult;
return cacheResult != null;
}
catch (DataCacheException dataCacheException)
{
switch (dataCacheException.ErrorCode)
{
case DataCacheErrorCode.KeyDoesNotExist:
case DataCacheErrorCode.RegionDoesNotExist:
return false;
case DataCacheErrorCode.Timeout:
case DataCacheErrorCode.RetryLater:
if (counter > 9) return false; // we tried 10 times, so we will give up.
counter++;
Thread.Sleep(100);
return TryGetFromCache(cacheKey, region, out cacheResult, counter);
default:
EventLog.WriteEntry(EventViewerSource, "TryGetFromCache: DataCacheException caught:\n" +
dataCacheException.Message, EventLogEntryType.Error);
return false;
}
}
}
Затем, когда нам нужно получить что-то из кэша, мы делаем:
TryGetFromCache(key, region, out cachedMapping)
Это позволяет нам использовать методы Try, которые заключают в себе исключения. Если он возвращает false, мы знаем, что с кешем что-то не так, и можем напрямую обращаться к SQL.