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

Reply via email to