Am I handling the ObjectScope the right way ?

14 posts, 1 answers
  1. julien test
    julien test avatar
    15 posts
    Member since:
    Oct 2009

    Posted 19 Dec 2009 Link to this post

    Hi,

    I'm wondering if I use the object scope correctly...

    I'm creating a web application.

    I created a Data access layer which is a class library with a static Class Datacontext.

    This static class has a member called scope which is initialized with a call to ObjectScopeProvider.GetNewObjectScope().

    Then I wrote a lot of static methods in the same DataContext class. These static methods get, add, update and delete the data, always using the same scope object. I carefully used transactions and exception handling with data modifications.

    Do I need to purge the scope object at some point, should I use several of them ? What's the best way to handle the scope in a web application scenario ? (I read about object scope in master pages but linking so strongly the rendering with the Data Access Layer keeps me sceptical about this way of managing the pb... I may be wrong though!)

    Thanks a lot for your help... I will need to deploy my web application in production shortly and I would like to make a smart use of our soon to be purchased open access ORM ;)

    Regards.
  2. TSE
    TSE avatar
    381 posts
    Member since:
    Sep 2008

    Posted 21 Dec 2009 Link to this post

    Hi Julien,

    In web apps the rule of thumb is:

    On request start get a new scope, store that scope somewhere where you can get hold of it during the request, and on request end dispose the scope again. Basically on thread (request) - one scope approach.

    I have implemented it for WCF in a layered architecture in this code library.
    It can easily be adopted to a plain web scenario. Basically you have to use some events (request start, request end) in the global.asax and call the Attach and Detach on your ContextManager.
    You will need though to write a WebContextManager, but it is really simple.. Use the WcfContextManager as template (only need to override a method) and then make this available in your ContextManagerFactory as a property.

    If this is too much work, Telerik also has some articles on the matter here.

    Regards

    Henrik
  3. DevCraft banner
  4. julien test
    julien test avatar
    15 posts
    Member since:
    Oct 2009

    Posted 21 Dec 2009 Link to this post

    Hi Henrik,

    Thanks a lot for your answer ! 

    I followed your advice and I used your wcf code library to implement and use a WebContextManager. It was a piece of work but I forced myself to do it and my solution is cleaner now ! 

    Now, my Global.asax looks like this:

    protected void Application_BeginRequest() 
            { 
                ContextManagerFactory.Default.Attach(); 
     
            } 
     
            protected void Application_EndRequest() 
            { 
                ContextManagerFactory.Default.Detach(); 
     
            } 

    Just one thing I have to ask you, for my web application, what can I use as a ContextKey ?

    For your WCF service you used :

    System.ServiceModel.OperationContext.Current.IncomingMessageHeaders.MessageId.ToString(); 

    What should I use? (the session ID ?)

    Thank you and merry Christmas !
  5. TSE
    TSE avatar
    381 posts
    Member since:
    Sep 2008

    Posted 21 Dec 2009 Link to this post

    Hi Julien,

    Glad you could use the code,

    In general you need the key to be something that is unique for each request, so that the same ObjectScope instance is returned from the ContextManagerFactory.Default.Current property..

    You could using the session ID. I have also seen the key to be extracted like this (in a Telerik sample):

    string key = context.GetHashCode().ToString("x") + Thread.CurrentContext.ContextID.ToString();

    where the context is the current instance of the HttpContext (aka HttpContext.Current)

    Regards

    Henrik
  6. Zoran
    Admin
    Zoran avatar
    534 posts

    Posted 22 Dec 2009 Link to this post

    Hello Julien,

     Just to add up to Henrik's suggestions and give you another option, one of the proven best practices among our clients is to use the HttpContext.Items collection for storing the scope during single request. You could have a look at this Knowledge Base article for more information on the approach.

    Kind regards,
    Zoran
    the Telerik team

    Instantly find answers to your questions on the new Telerik Support Portal.
    Watch a video on how to optimize your support resource searches and check out more tips on the blogs.
  7. TSE
    TSE avatar
    381 posts
    Member since:
    Sep 2008

    Posted 22 Dec 2009 Link to this post

    Hi Zoran,

    Thanks for joining in.
    As always there are many ways to achieve the goal. In a pure web scenario I like the implementation you referenced.

    In fact I referenced (credits goes your way) the key "generation" from the very same KB article.

    Regards

    Henrik
  8. Chris Jansen
    Chris Jansen avatar
    7 posts
    Member since:
    Sep 2009

    Posted 22 Dec 2009 Link to this post

    Henrik-

    Thanks also from me. I was searching through the forums and found your post and the link to your code sample. I think this is just what I'm looking for for the WCF project I'm working on. I had a couple of questions:

    1. We're currently experiencing exceptions of the type below when making WCF service calls in rapid succession. In your experience, how likely is this exception caused by not properly handling the ObjectScope?
    2. How scalable is the solution you provided for handling ObjectScope? I'm mainly curious about how well the Dictionary at the heart of the BaseContextManager scales.

    Thanks!

    Telerik.OpenAccess.Exceptions.DataStoreException: Telerik.OpenAccess.RT.sql.SQLException: Please check, that the genericADO2 driver is not used with SQL Server 2000 as it does not support MARS; please use instead in the backendconfigurat 
    ion element: backend="mssql" driver="ntds" 
     ---> System.InvalidOperationException: SqlConnection does not support parallel transactions. 
     
  9. TSE
    TSE avatar
    381 posts
    Member since:
    Sep 2008

    Posted 23 Dec 2009 Link to this post

    Hi Chris,

    Thanks for joining us, glad you could use the code sample.

    About your questions:

    1)
    I don't think it has to do with the handling of the scope (in respect to the ContextManager, I could be wrong though), except if the message id (used as key for the dictionary) is actually the same for some of the requests.. Is shouldn't be as per WCF docs.
    What backend are you using? mssql 2000, 2005, 2008?


    2)
    As for the scalability, it scales as good as the dictionary does, as you already pointed out. The point is that the dictionary (or whatever means you use to store the context in) has to thread safe, thus I used the lock block around access to the dictionary.
    I use the same mechanism for a large production system and haven't found any scalability or performance issues yet.

    How rapid is rapid? One request per second? Or?

    Aside:
    I am currently working on another implementation of scope handling in WCF, which uses the features of WCF more extensively and also uses the Unity Depency Injection. Meaning that all you have to do is to do as a developer is to mark your business layer or repository class as having a depency on the context and then Unity will inject the correct instance of the context in your class.

    Regards

    Henrik

  10. Answer
    Zoran
    Admin
    Zoran avatar
    534 posts

    Posted 23 Dec 2009 Link to this post

    Hello Henrik and Chris,

    The exception Chris pointed out means that one scope was shared between two threads which should never happen in the scenario we are discussing. We can not be sure of the reason why this has happened, but we could suggest an option in the configuration that will make proper handling for such cases:
    You could put the following entry in the backendConfiguration section of your app.config file:
    <option.Multithreaded>True</option.Multithreaded>
    Nevertheless, the better  approach towards solving the problem would be to find out the reason for the sharing of the scope between threads that make different requests to the database and try to avoid that.

     

    Regards,
    Zoran
    the Telerik team

    Instantly find answers to your questions on the new Telerik Support Portal.
    Watch a video on how to optimize your support resource searches and check out more tips on the blogs.
  11. TSE
    TSE avatar
    381 posts
    Member since:
    Sep 2008

    Posted 23 Dec 2009 Link to this post

    Hi Zoran,

    Thanks for joining us again and enlightening us the details for the exception.

    When it must be the handling of scope in the ContextManager as it serves the WCF services and layers below with the scope, although I really can't see where it hangs, except as pointed out... if the WCF message id is the same among request.

    To check against this you could append the current managed thread id to the key in the WcfContextManager implementation of GetContextKey like:

    key = (wcf message id as in the sample) + Thread.CurrentThread.ManagedThreadId.ToString()

    Also Chris:
    Make sure that you do no get an object scope in other ways as going through the ContextManagerFactory.Default.Current.

    Regards
    Henrik
  12. Chris Jansen
    Chris Jansen avatar
    7 posts
    Member since:
    Sep 2009

    Posted 27 Dec 2009 Link to this post

    Thank you Henrik and Zoran for your help and suggestions!

    Henrik, to clarify, the exception we have been seeing is without implementing the context manager to use the same ObjectScope for each incoming request.

    Although I still want to implement the context manager for ObjectScope management, it looks like I have some more research to do to find the root cause of the exception I was getting.

    Chris

  13. Myth
    Myth avatar
    54 posts
    Member since:
    Jan 2010

    Posted 22 Feb 2010 Link to this post

    How about when using ORM in a regular application? Not when using WCF services. right now i've been using just 1 scope provider from program start to program close. I figured this would have been better for object caching?
  14. Zoran
    Admin
    Zoran avatar
    534 posts

    Posted 25 Feb 2010 Link to this post

    Hello Myth,

    Yes, for desktop applications it is OK for one to use one object scope and do all operations with it. You should only beware of making nested transactions if more than one user access that application. That is one of the common mistakes by our customers in these kind of scenarios.

    All the best,
    Zoran
    the Telerik team

    Do you want to have your say when we set our development plans? Do you want to know when a feature you care about is added or when a bug fixed? Explore the Telerik Public Issue Tracking system and vote to affect the priority of the items.
  15. Myth
    Myth avatar
    54 posts
    Member since:
    Jan 2010

    Posted 26 Feb 2010 Link to this post

    Hi Zoran,

    Thanks for the answer!

    Kind regards
Back to Top
DevCraft banner