Thanks once again James! I'll look into UnitOfWork.
And yes, I do use transactions, but only for each method inside the TaskDao. (Each method in the TaskDao could be doing more than one query all of which are in a transaction). cheers Krishna. On Oct 8, 2:43 pm, "James Kovacs" <[EMAIL PROTECTED]> wrote: > 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/rhi... > > 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 - Architecthttp://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 -- 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 -~----------~----~----~----~------~----~------~--~---
