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
-~----------~----~----~----~------~----~------~--~---

Reply via email to