Generally you would use a UnitOfWork within UpdateTasks and share a common session via the UnitOfWork. You can find a good implementation of the pattern using NHibernate in Ayende's RhinoCommons. (I have my own implementation, but Ayende's is publicly available.) *svn checkout * https://rhino-tools.svn.sourceforge.net/svnroot/rhino-tools/trunk
The code you want to look at is here: https://rhino-tools.svn.sourceforge.net/svnroot/rhino-tools/trunk/rhino-commons/Rhino.Commons.NHibernate/UnitOfWork/ Basically you would: using(UnitOfWork.Start()) { // code } Within your DAO, you call UnitOfWork.CurrentSession to retrieve the current NHibernate to work with. The current IUnitOfWork and ISession are stored in either a thread-static variable (non-web) or HttpContext.Current.Items (web). BTW - NH2 requires transactions. So I would recommend explicitly delineating transactions within your code. HTH, James -- James Kovacs, B.Sc., M.Sc., MCSD, MCT Microsoft MVP - Architect http://www.jameskovacs.com [EMAIL PROTECTED] 403-397-3177 (mobile) On Tue, Oct 7, 2008 at 9:28 PM, Krishna <[EMAIL PROTECTED]> wrote: > > James, > > Thanks for the reply. Good to know that the pattent I'm using is > recommended. > > I do keep the session factory in a singleton class. > > I kept wondering though, if opening up a session for every method call > was too much of an overhead. For example consider a method, > with the following code:- (there may be syntax errors, so pls ignore, > I'm typing this in not copy-paste): > > public void UpdateTasks(string[] taskIds){ > foreach (string taskId in taskIds){ > if (TaskDao.TaskExists(taskId)){ > throw new ArgumentException("Could not > find task for id: " + taskId); > } > if (TaskDao.GetTaskStatus(taskId) != > TaskStatusType.Active){ > throw new > InvalidOperationException("Cannot update inactive tasks"); > } > > TaskDao.UpdateTask(taskId); //this does some updates > - does not matte what, for this example > } > } > > (error handling etc not shown, but yes every exception disposes off > the session and rollsback any transactions) > > In the above code, there are 3 calls to the TaskDao. Each call opens > its own session. I would consider the UpdateTasks to be a unit of > work. So isn't it better to somehow have one session for all these 3 > calls to the TaskDao, as opposed to just one? > > Is there a recommended way to do that in non-web contexts. If there is > a long-running thread, and that decides to call UpdateTasks once every > 2 or 3 seconds to update some task information. > How do we then manage the sessions in that situation? Is opening up a > new session for every method call to TaskDao still OK ? > > Cheers > Krishna > > On Oct 7, 3:05 am, "James Kovacs" <[EMAIL PROTECTED]> wrote: > > Hi, Krishna, > > What you're doing is not an anti-pattern, but a NHibernate Best Practice > > (TM). Sessions are very lightweight and should be created and disposed > > quickly as you're doing. It is an anti-pattern to re-use sessions across > > logical units of work. (BTW - If an exception is thrown, the session will > be > > left in an indeterminate state. It should be thrown away and a new one > > created.) > > > > SessionFactory is the heavyweight piece and should be built once, which > it > > sounds like your'e doing. Your SessionFactory instance should be stored > in > > some thread static variable for repeated use. (It's thread-safe. So no > need > > to manually synchronize it.) > > > > HTH, > > James > > -- > > James Kovacs, B.Sc., M.Sc., MCSD, MCT > > Microsoft MVP - C# Architecturehttp://www.jameskovacs.com > > [EMAIL PROTECTED] > > 403-397-3177 (mobile) > > > > > > > > On Sun, Oct 5, 2008 at 2:30 AM, Krishna <[EMAIL PROTECTED]> wrote: > > > > > Hi all, > > > > > I'm developing and application that runs as a Windows service. There > > > are other components which include a few WCF services, a client GUI > > > and so on - but it is the Windows service that access the database. > > > > > So, the application is a long-running server, and I'd like to improve > > > its performance and scalability, I was looking to improve data access > > > among other things. I posted in another thread about second-level > > > caching. > > > > > This post is about session management for the long-running thread that > > > accesses the database. > > > Should I be using a thread-static context? > > > If so, is there any example of how that would be implemented. > > > > > Every one around the net who is using NHibernate seem to be heavily > > > focussed on web-application style architectures. There seems to be a > > > great lack of documentation / discussion for non-web app designs. > > > > > At the moment, my long running thread does this: > > > > > 1. Call 3 or 4 DAO methods > > > 2. Verify the state of the detached objects returned. > > > 3. Update the state if needed. > > > 4. Call a couple of DAO methods to persist the updated instances. > > > (pass in the id of the object and the instance itself - the DAO will > > > retrieve the object from the DB again, and set the updated values and > > > session.SaveOrUpdate() before committing the transaction. > > > 5. Sleep for 'n' seconds > > > 6. Repeat all over again! > > > > > So, the following is a common pattern we use for each of the DAO > > > methods: > > > > > - Open session using sessionFactory.OpenSession() > > > - Begin transaction > > > - Do db work. retrieve / update etc > > > - Commit trans > > > - (Rollback in case of exceptions) > > > - Finally always dispose transaction and session.Close() > > > > > This happens for *every* method call to a DAO class. > > > I suspect this is some sort of an anti-pattern the way we are doing > > > it. > > > > > However, I'm not able to find enough direction anywhere as to how we > > > could improve it. > > > > > Pls note, while this thread is running in the background, doing its > > > stuff, there are requests coming in from the WCF clients each of which > > > could make 2-3 DAO calls themselves - sometimes querying/updating the > > > same objects the long running thread deals with. > > > > > Any ideas / suggestions / pointers to improve our design will be > > > greatly appreciated. > > > > > Krishna- Hide quoted text - > > > > - Show quoted text - > > > --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "nhusers" group. To post to this group, send email to [email protected] To unsubscribe from this group, send email to [EMAIL PROTECTED] For more options, visit this group at http://groups.google.com/group/nhusers?hl=en -~----------~----~----~----~------~----~------~--~---
