OpenAccess L2 cache with Sitefinity...

2 posts, 0 answers
  1. Nathan
    Nathan avatar
    1 posts
    Member since:
    Jun 2012

    Posted 07 Oct 2013 Link to this post

    Hi,

    I am experiencing some problems with OpenAccess L2 cache and I will try to explain them in text below.

    Recently, I've upgraded Sitefinity 5.1 to 6.1 based on documentation from your site. 
    I followed every step in there and successfully logged in just to confirm that I am now at version 6.1.

    During this process I've also upgraded OpenAccess to version (2013.2.611.1) that is used by Sitefinity itself.
    I've did this in order to test L2 cache behaviour with this new Sitefinity version.

    We use OpenAccess in our project with L2 cache turned on with settings like on attached picture.
    In the past, from time to time, we had to use Evict statement in our code to make cache reload some entities that were not properly loaded after update.
    This was the case when we were using database views to show some data, but it also happened with some entities generated from database tables.

    So, first thing that I did when Sitefinity upgrade is finished is to remove Evict statements and retest L2 cache issues.
    After that I could confirm that our problems with L2 cache are still there - I've created new entity (I will use 'Student' as this entity name), 
    successfully saved new student to DB, but that student was not visible in student list (this list is populated by view) until I restarted app pool.

    Can U give me more info on L2 cache and how it is supposed to work with table and view entities?

    Thanks in advance
  2. Kaloyan Nikolov
    Admin
    Kaloyan Nikolov avatar
    118 posts

    Posted 09 Oct 2013 Link to this post

    Hello Nathan,

    I can confirm you that your initial approach is correct and valid.
    You should manually handle the dependencies between entities and views. If you update an entity using the Telerik OpenAccess ORM or by invoking a stored procedure the corresponding entities loaded via views in the L2 cache (if any) will not be automatically evicted. The reason for this is that the dependency between the tables and the views is expressed by the SQL statements used in the views. When an entity is updated/deleted/inserted we cannot determine which of the views could be affected. We do not plan to change this behavior so you can add again your manual evictions in your code. 

    I can suggest you to handle such dependency with one of the following approaches: 
    1. If you can identify all places where you manipulate entities used in your views you can evict the dependent classes from the L2 cache manually. 

    2. In case you cannot identify all places where you manipulate the target entity types (or they are too many) you could override the OpenAccessContext Init(...) method and subscribe for the Added, Changed and Removed events. Then you can analyze if you should evict the views based on the type of the entity. The best way to do this is in a separate partial class as shown below:

    public partial class EntitiesModel1
    {
        Type carType = typeof(Car);
        Type categoryType = typeof(Category);
       
        protected override void Init(string connectionString, BackendConfiguration backendConfiguration, MetadataContainer metadataContainer)
        {
            base.Init(connectionString, backendConfiguration, metadataContainer);
       
            if (backend.SecondLevelCache.Enabled)
            {
                this.Events.Added += Events_Added;
                this.Events.Changed += Events_Changed;
                this.Events.Removed += Events_Removed;
            }
        }
       
        void Events_Removed(object sender, RemoveEventArgs e)
        {
            EvictIfCarOrCategory(e.PersistentObject);
        }
       
        void Events_Changed(object sender, ChangeEventArgs e)
        {
            EvictIfCarOrCategory(e.PersistentObject);
        }
       
        void Events_Added(object sender, AddEventArgs e)
        {
            EvictIfCarOrCategory(e.PersistentObject);
        }
       
        private void EvictIfCarOrCategory(object persistentObject)
        {
            var poType = persistentObject.GetType();
            if (poType == carType || poType == categoryType)
            {
                this.LevelTwoCache.EvictAll<CarsAndCategories>();
            }
        }
    }

    NOTE: the second approach is more automated but you should consider that the type checks will happen for each added/deleted/updated entity. In some cases this could affect the application performance. 

    I hope this helps. Please do not hesitate to get back to us with further questions.


    Regards,
    Kaloyan Nikolov
    Telerik
    OpenAccess ORM Q3 2013 Beta is available for immediate download in your account. Get it now and play with the latest bits. See what's new >>
  3. DevCraft banner
Back to Top