I have a few long running tasks on my server. Basically they are like scheduled tasks - they run from time to time.
They all required access to the DB and I use Entity Framework for that. Each task uses a DbContext for access.
Should the DbContext object be recreated on every run or should I reuse it?
I should say "it depends" as there are probably scenarios where both answers are valid, however the most reasonable answer is "the context should be disposed as soon as it is not needed" which in practice means "dispose rather sooner than later".
The risk that comes from such answer is that newcomers sometimes conclude that the context should be disposed as otfen as possible which sometimes lead to a code I review where there are consecutive "usings" that create a context, use it for one or two operations, dispose and then another context comes up next line. This is of course not recommended also.
In case of web apps, the natural lifecycle is connected with a lifecycle of web requests. In case of system services / other long running applications one of lifecycle strategies is "per business process instance" / "per usecase instance" where business processing / use case implementations define natural borders where separate instances of contexts make sense.
Yes, DbContext should only live for a very short time. It is effectively your unit of work
You should definitely create it each time you're going to use it. (Well, you should inject it but that's another discussion :-))
Update : OK, I accept that 'create it each time you're going to use it' could be misleading. I'm so used to context being an instance on a class that is injected and so lives only for the life of a request that I struggle to think of it any other way... #wiktor's answer is definitely better as it more correctly expresses the idea that you should "dispose sooner rather than later"
Related
For a REST api, that has no dependencies between requests and is using ASP.NET Core DI.
I have heard conflicting arguments when choosing the most appropriate:
Prefer transient and then scoped and avoid singleton due to memory and multi-threading issues and also because singletons should not be injected with other lifetimes due to captive dependencies
Prefer singletons to save time instantiating objects and prevent opening multiple connections
I understand they work differently but is there a 'go-to' lifetime? Should it start with 'transient' and move to others as required?
Are there any investigations proving the instantiation time saved by singleton is actually relevant?
I'm not going to say there's a right or wrong way here, but I'll share my personal experience.
I've tried both ways, and ended up finding that it's best to start with transient and then expand the scope as necessary.
Think in terms of the Single Responsibility Principle and Reasons for Change. The reason that your service's lifetime scope may need to change will likely be linked to a change you make to the service implementation itself. When that Reason happens, you want to only need to change a single class.
If you have a service that needs to be longer-lived than most of your other services, all you have to do is make it longer-lived and inject factories for any shorter-lived dependencies into it.
On the other hand, if you have a class that needs to be shorter-lived than most of your other services, you'll end up having to inject it as a factory into all the longer-lived services. So one Reason for Change impacts code all over your code base.
Of course, this is assuming you're doing things correctly: avoiding captive dependencies and remembering to make non-thread-safe services transient. I find it's far easier to remember which services need to be long-lived and override the defaults in that direction, than it is to remember which services shouldn't be long-lived and override the defaults that way. And I've found that failure to do the latter leads to much more insidious bugs that are harder to notice and result in greater damage.
With regards to performance: I haven't done performance testing with the ASP.NET Core built-in DI framework, but I've found that SimpleInjector is fast enough that the time and memory overhead of creating new instances of services is trivial in comparison with the other work my app does (like querying databases).
With regards to preventing opening multiple connections: SQL Server connections are pooled automatically so the cost to creating a new SqlConnection() and disposing it several times in a request is generally pretty trivial.
Should it start with 'transient' and move to others as required?
Yep. Transient services are simpler to implement correctly, and simply instantiating an object every time a dependency is resolved would normally not cause a significant performance problem.
I'm struggling with the following problem.
I have a database with a table Jobs, which contains information about Jobs to be done. I followed the Code First approach of EF 6.0 and create a POCO class called Job. I then query the database for the Jobs:
DbSet<Job> receivedJobs;
using (var context = new MyContext())
{
receivedJobs = (from j in context.Jobs
select j);
}
With the received set receivedJobs I will then do a time consuming optimization.
As I understand it, the lifetime of the context as well as the resources the context controls ends with the closing bracket of the using statement. Also a good design should free resources to the database as soon as it is no longer required.
My question is now what should I do in my case? Just keep the database context alive until I finished my time consuming optimisation task. Or close the connection as it is not needed until the optimisation ends. But in the latter case what do I do with the disposed Job objects, because I will then need to access some navigation properties of them which I can't because the context was closed. (And by the way the data in the instances of the Job class will not be changed by the optimization. So it is not required to keep track of changes to these objects, because there will be none)
Hope someone can help me to understand what is the recommended design in this case.
Best regards
You should always hold a context for the least amount of time necessary to do the operations. In your case, it sounds like you will need the context until the optimization is done because you are using some of its methods for navigating the result set. If that is the case, then the context should be held until you don't need it.
The bad habit to avoid is to hold onto a context when you have no immediate need for it. You will see some applications that wrongly create a context on application start and hold it for the life of the application. That is bad and a waste of resources.
In your case, put the optimization code in place, use the context until the code is completed, then release the context. Your using statement will take care of all the messy disposal stuff. Just get your code that needs the context in the {} for the using and you should be good to go.
Altough it will not solve all of your issues, specially the design ones,do you know the "Include" function which preloads the navigation properties of you jobs?
For example if a job points to a list of Tasks thanks to property named "Tasks":
context.Jobs.Include("Tasks") //will preload the Tasks property of
your job.
context.Jobs.Include("Tasks.AllowedUsers") //will preload the Tasks
property of your job, and the AllowedUsers list of each task.
If you want to preload several properties at same level, just use something like:
context.Jobs.Include("Tasks").Include("OtherTasksOnJob")
I see there are 2 possible scenarios as to the session handling:
Open one single ISession per request. Open it at request start and close it at request end.
Open one ISession per conceptual "unit of work". Many sessions are created for a request.
The approach #1 is the one I'm doing now. I'm a little bit worried about it because, although it works, it's a little bit difficult to debug. For instance, I have an object not being saved (even though I ordered it to) and I'm having trouble debugging since there's a LOT of things happening during a complete request life-cycle.
The approach #2 seems to be the standard best-practice (not sure about ASP.NET) and I'm sure it's pretty easier to debug. The problem I see is about inter-session communication. For instance: My Page class holds a reference to the User, which is a persistent object. Many of the operations receive the user as parameter. As the user belongs to a different session, I can't pass it as a parameter.
I'm biased to #2, but I don't know if it's the best practice, nor how to deal with cross-session object.
Thanks.
Most people do Session-Per-Request for the reasons you outline and for simplicity.
However, you can open and commit transactions for each "unit of work". So you will have many transactions for each session. (It is also usual practice to make sure that when the transaction is committed, the session is flushed at the same time).
For example, after clicking the save button, open and commit a transaction.
The session will take care of keeping track of all your entities. The transaction will take care of flushing to the database when necessary.
With this setup it should be easier to debug your problem.
For the ASP.NET project I'm working on now, I use a combination of these approaches.
I open an ISession at the beginning of a request and close it at the end of the request, as you do with your first approach, and I use the session to load any entities that need to remain attached to a session for the duration of the request.
However, when I need to save or update or delete an entity, I create a new transient object and hand it to a new ISession, separate from the one tied to the request. For additional units of work, I create additional sessions.
You may find NHibernate Burrow helpful, or at least interesting in this regard, as it is designed to assist with session management in ASP .NET applications, implementing the concept of a "long-running conversation" that spans multiple requests.
I think your real question is why cant I get my objects to save.
Even thought you are using a single ISession you still need to either Flush the session or commit transaction for some Save/Update/Delete actions to be commited.
i have a client server application, the server uses nhibernate.
i wanna know how should i use the session?
per call?
per client?
single?
other way?
and how can i keep the session cache in the server ?
and also i wanna know if the session is thread safe?
You should use one session per unit of work. If that includes multiple operations, so be it.
Use the session.BeginTransaction() to wrap the unit of work and commit once all the items are done.
Sessions are NOT thread safe, but the session factory is (which you definitely want to keep around).
NHiberate has various cache options for data, but the sessions are meant to be used and disposed.
Normally it's done one per request. You can create HttpApplication, which opens the session at the beginning of request and closes at the end of request (example).
Per call should be the usual solution
There really is no one right answer to the question of session lifetime. You can make any session lifetime work, it depends on your requirements. Sessions are not thread safe, but session factories are.
To keep the cache around, you need to keep the session around. It is likely to be fairly challenging to keep the cache around and keep the cache correct in anything but simple single user, single process applications.
There's a great example I've used from NHibernate Best Practices.
The code example uses a session per ASP.NET request.
I've seen a lot of discussion about this subject on here.
If i have a static class w/ static methods that connects to a database or a server, is it a bad idea to use this in a multi-user environment (like a web page)? Would this make a new user's tread wait for previous users' threads to finish their calls before accepting a new one?
What would be the implications of this with multi-threading, also?
Thx!
If each static method is fully responsible for acquiring its resources and then disposing its resources within the scope of the method call (no shared state), then you shouldn't have any problem with threading that you wouldn't have using instance classes. I would suggest, however, that the bigger problem is that a reliance on public static methods (in static or non-static classes) creates many other design problems down the road.
First of all, you're binding very tightly to an implementation, which is always bad.
Second, testing all of the classes that depend on your static methods becomes very difficult to do, because you're locked to a single implementation.
Third, it does become very easy to create non-thread safe methods since static methods can only have static state (which is shared across all method calls).
Static methods do not have any special behaviour in respect to multithreading. That is, you can expect several "copies" of the method running at the same time. The same goes for static variables - different threads can access them all at once, there is no waiting there. And unless you're careful, this can create chaos.
Yes it's a bad idea.
When you use one connection for all your users if someone performs an action that requires, lets say 15 seconds, just for database access, all other users will have to wait in order to connect to the database
A little weirded out by this question. As to why you have so much static going on.
But I think you're asking about threading issues, so I would say go check out some of the docs on threading
http://msdn.microsoft.com/en-us/library/c5kehkcz(VS.80).aspx
Static is only defining the scope where the method is defined, and how it is bound / called. It has nothing to do with multi threading.
You need to be careful with static fields. They are shared by all threads. Threads are not waiting for each other, but you need locks to make it work.
But if your application is a bit more complex than Hello World, you should consider to have you methods not static but to use object oriented patterns.
If you do it right, it won't be a problem. If you do it wrong, it has the potential force sequential access to the resource.
Sometimes the difference between right and wrong can be very subtle and hard to spot, but the main thing is that no method should rely on or lock any "state" (members) of the class.
If you use one static connection to access the database, you will have to synchronize method calls. Multiple threads asking the database for data over a single connection will ... ehhmmm ... mess things up. So you are serializing all threads' data access and this will have a large impact on the performance.
If every call opens its own connection, you do not need to serialize all threads because there is no shared connection. Creating a connection per request is still an expensive design.
If you use a static connection pool you will reduce this performance impact because you only need to serialize the access to the connection pool.
Further, statics are in general not a good design decission - they make unit testing very complicated. You should consider using the Singleton or Monostate pattern.
I use static method for lookup objects. I can manage all lookups objects in one place (using caching) for the asp.net application and all methods call it by using static method.
By this way, I do not need to instantiate lookups objects everytime I need it and it reduce the need to call DB for performance enhancement.