Sharing Enterprise Library Database Cache between

2019-09-02 15:18发布

问题:

I'm having a strange problem with the Enterprise Library 5 Caching Block where two applications are sharing the same database cache. I've written a very simple static cache manager class which wraps up creating the EntLib5 ICacheManager, and reading/writing to it.

private static ICacheManager _manager = null;

private static ICacheManager Manager
{
    get
    {
        lock (ClientLock)
        {
            if (_manager == null)
                _manager = CacheFactory.GetCacheManager();

            return _manager;
        }
    }
}

public static object Get(string cacheKey)
{
    return Manager.GetData(cacheKey);
}

public static void Add(string cacheKey, object cacheItem)
{
    Manager.Add(cacheKey, cacheItem);
}

My database is setup correctly as are the configuration files and I can read & write to the database cache from a single console application with no problems.

However I'm trying to do a test between two applications sharing the same cache. The problem seems to be that if the Static CachingManager class in Console_A adds items to the Cache, after Console_B has instantiated it's static CacheManager, the changes are not picked up by Console_B.

Here's a quick timeline to explain.

Start Console_A

Write Item1 from Console_A to Cache - (Static ICacheManager created with noticeable 1sec pause) Success - 1 Item in Cache
Write Item2 from Console_A to Cache - Success - 2 Items in Cache
Write Item3 from Console_A to Cache - Success - 3 Items in Cache

Start Console_B

Read Item1 from Cache to Console_B - (Static ICacheManager created with noticeable 1sec pause) - Success - 3 Items in Cache
Read Item2 from Cache to Console_B - Success - 3 Items in Cache
Read Item3 from Cache to Console_B - Success - 3 Items in Cache

Write Item4 from Console_A to Cache - Success - 4 Items in Cache (Confirmed in DB)
Read Item4 from Cache to Console_B - Failure - 3 Items in Cache

So it seems that once Console_B initially sets up it's cache manager, it doesn't go back to the database to refresh the data. the Contains

I've tried removing the if(_manager == null) check from my Property as well so that it pulls a new CacheManager from the factory everytime but it made no difference.

Any advice appreciated.

EDIT

It would seem that the LoadItems Sproc only gets called when the ICacheManager is instantiated but never again during the application life cycle regardless of whether you call the CacheFActory / Unity EntLibContainer again.

回答1:

The application domain of Console_A and Console_B are different. Even though you've defined your cache manager to be static it will not exist beyond the application domain therefore you have in reality two separate cache managers that do not know about each other.

I'd recommend using a service (WCF) and calling your business methods through that service, that way all console applications will be calling the same service and it will have one instance of a cache manager residing in it's own application domain.



回答2:

This is by design.

The enterprise library caching block is designed as an In Process Cache, and even when using a DB Based backing store, that's only for State Recovery in the event you're application is restarted. It was not designed to be used as a distributed cache.

Ref: Chris Tavares - MS Patterns & Practices Team