This is a migrated thread and some comments may be shown as answers.

Am I handling the ObjectScope the right way ?

13 Answers 224 Views
Development (API, general questions)
This is a migrated thread and some comments may be shown as answers.
This question is locked. New answers and comments are not allowed.
julien test
Top achievements
Rank 1
julien test asked on 20 Dec 2009, 01:46 AM
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.

13 Answers, 1 is accepted

Sort by
0
IT-Als
Top achievements
Rank 1
answered on 21 Dec 2009, 08:22 AM
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
0
julien test
Top achievements
Rank 1
answered on 21 Dec 2009, 01:28 PM
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 !
0
IT-Als
Top achievements
Rank 1
answered on 21 Dec 2009, 02:42 PM
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
0
Zoran
Telerik team
answered on 22 Dec 2009, 09:55 AM
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.
0
IT-Als
Top achievements
Rank 1
answered on 22 Dec 2009, 12:35 PM
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
0
Chris Jansen
Top achievements
Rank 1
answered on 22 Dec 2009, 05:57 PM
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. 
 
0
IT-Als
Top achievements
Rank 1
answered on 23 Dec 2009, 08:32 AM
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

0
Accepted
Zoran
Telerik team
answered on 23 Dec 2009, 09:02 AM
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.
0
IT-Als
Top achievements
Rank 1
answered on 23 Dec 2009, 09:17 AM
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
0
Chris Jansen
Top achievements
Rank 1
answered on 27 Dec 2009, 05:10 PM
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

0
Myth
Top achievements
Rank 1
answered on 22 Feb 2010, 03:57 PM
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?
0
Zoran
Telerik team
answered on 25 Feb 2010, 07:13 PM
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.
0
Myth
Top achievements
Rank 1
answered on 26 Feb 2010, 06:58 AM
Hi Zoran,

Thanks for the answer!

Kind regards
Tags
Development (API, general questions)
Asked by
julien test
Top achievements
Rank 1
Answers by
IT-Als
Top achievements
Rank 1
julien test
Top achievements
Rank 1
Zoran
Telerik team
Chris Jansen
Top achievements
Rank 1
Myth
Top achievements
Rank 1
Share this question
or