Implicit transactions

27 views
Skip to first unread message

Vladan Strigo

unread,
Sep 21, 2009, 7:51:27 AM9/21/09
to S#arp Architecture
Hi,

I've been thinking about this for a while...in NH its recommended to
put in transaction even the read operations. But to do something like:

Employee employee;
using (var tran = session.begintransaction())
{
employee = somerepository.get<Employee>(1);
}

sounds like alot of code which could be minimized...I've had an idea,
only didnt test till now that Session.Transaction.IsActive could be
the key, and this morning read an article:

http://nhforge.org/blogs/nhibernate/archive/2009/09/20/part-10-testing-and-refactoring.aspx
(find WrapInTransaction method) which does exactly what I had in
mind...

so if there is an active transaction, use it, if not, create
one...this would make this code minimized to only this:

Employee employee = somerepository.get<Employee>(1);

(this, of course is only valid for single operation transactions).


What do you think?


Vladan

Vladan Strigo

unread,
Sep 22, 2009, 7:04:23 AM9/22/09
to S#arp Architecture
any opinions?



On Sep 21, 1:51 pm, Vladan Strigo <vla...@strigo.net> wrote:
> Hi,
>
> I've been thinking about this for a while...in NH its recommended to
> put in transaction even the read operations. But to do something like:
>
> Employee employee;
> using (var tran = session.begintransaction())
> {
>    employee = somerepository.get<Employee>(1);
>
> }
>
> sounds like alot of code which could be minimized...I've had an idea,
> only didnt test till now that Session.Transaction.IsActive could be
> the key, and this morning read an article:
>
> http://nhforge.org/blogs/nhibernate/archive/2009/09/20/part-10-testin...

Martin Hornagold

unread,
Sep 22, 2009, 7:07:49 AM9/22/09
to sharp-arc...@googlegroups.com
The simplest way of dealing with transactions in S#arp is to put the [Transaction] attribute on all action methods that contain database calls.

Simone Busoli

unread,
Sep 22, 2009, 7:10:01 AM9/22/09
to sharp-arc...@googlegroups.com
I think that transactions are a cross cutting concern, therefore they should be tackled with AOP.

Tom Cabanski

unread,
Sep 22, 2009, 7:38:46 AM9/22/09
to sharp-arc...@googlegroups.com
Isn't the Transaction attribute in SharpArch exactly what you are talking about?

--
Tom Cabanski
Vice President of Technology
Onpoint On Demand (Houston Office)
4801 Woodway Drive
Suite 300 East
Houston, TX 77056
Direct: 713-962-2638
http://www.onpointod.com

Kyle Baley

unread,
Sep 22, 2009, 8:54:26 AM9/22/09
to sharp-arc...@googlegroups.com
The transaction support is something that I think needs some love. At the moment, transaction support is only at the controller level. I.e. you can't make a service call transactional. Unless you call out to the DbContext method on a repository which I think is a leaky abstraction. Even at the controller level, you still need to manually rollback a database transaction if anything goes wrong.

I like the idea of everything being transactional by default and maybe explicitly specifying when you *don't* want to use one.

Simone Busoli

unread,
Sep 22, 2009, 8:55:37 AM9/22/09
to sharp-arc...@googlegroups.com
Kyle, this is easilly accomplished with windsor and interceptors.

Kyle Baley

unread,
Sep 22, 2009, 9:00:07 AM9/22/09
to sharp-arc...@googlegroups.com
Which part? Making the service call transactional or making everything transactional by default? In either case, is this something that should be incorporated into S#arp?

Simone Busoli

unread,
Sep 22, 2009, 9:02:00 AM9/22/09
to sharp-arc...@googlegroups.com
The first part. BTW, transaction boundaries should be, well, at the boundaries, therefore on your controllers or web service endpoints.
WRT everything transactional by default I don't think it should be a part of the project.

Kyle Baley

unread,
Sep 22, 2009, 10:55:03 AM9/22/09
to sharp-arc...@googlegroups.com
That's a good point about it being at the boundaries. I can't think of an example of where I'd like to make the service call transactional but not the controller method.

Then again, are transactions typically part of the business rules? I.e. If we want three things saved in a transaction, should it be closer to the domain?

Simone Busoli

unread,
Sep 22, 2009, 11:47:38 AM9/22/09
to sharp-arc...@googlegroups.com
I don't see them as part of the business rules, but at times there's something that makes me think about transactions when I'm into the domain. Not everything you are doing might be transactional, think about email notifications.

If you need to confirm a user about its registration, you might:

- register the user, but fail to send the notification -> the transaction is rolled back and nothing happens
- send the notification, but fail to save the user -> the transaction is rolled back but the email has already been sent

I think an ideal way to manage these things is to have non transactional resources behave like transactional ones. In the example above

- even if the notification fails, retry until it succeeds and therefore don't rollback the transaction
- if the database save doesn't succeed, "undo" the send

this can be accomplished in several ways, of which I don't know which are the best ones. Among them asynchronous messaging and out of process batch operations.

Kyle Baley

unread,
Sep 22, 2009, 2:43:13 PM9/22/09
to sharp-arc...@googlegroups.com
Yeah, we need to think of transactions as more than a database operation. Manipulating a file is another example.

Frank

unread,
Sep 22, 2009, 4:20:02 PM9/22/09
to S#arp Architecture
I've run across this exact same scenario and my solution was to use
the System.TransactionScope to wrap the database and email interaction
across one distributed transaction. I believe that
System.TransactionScope uses MSDTC under the hood, which coordinates
with database and non-database resources alike, such as an smtp
server.

I've pondered the idea of extending the [Transaction] attribute so
that it uses TransactionScope instead of just the NHibernate one. If
I'm not mistaken, an ADO.NET connection will automatically work within
the context of an MSDTC transaction...
> > On Tue, Sep 22, 2009 at 9:02 AM, Simone Busoli <simone.bus...@gmail.com>wrote:
>
> >> The first part. BTW, transaction boundaries should be, well, at the
> >> boundaries, therefore on your controllers or web service endpoints.
> >> WRT everything transactional by default I don't think it should be a part
> >> of the project.
> >> On Tue, Sep 22, 2009 at 15:00, Kyle Baley <k...@baley.org> wrote:
>
> >>> Which part? Making the service call transactional or making everything
> >>> transactional by default? In either case, is this something that should be
> >>> incorporated into S#arp?
>
> >>> On Tue, Sep 22, 2009 at 8:55 AM, Simone Busoli <simone.bus...@gmail.com>wrote:
>
> >>>> Kyle, this is easilly accomplished with windsor and interceptors.
>

Simone Busoli

unread,
Sep 22, 2009, 4:42:11 PM9/22/09
to sharp-arc...@googlegroups.com
I never used the DTC, I don't know how well it could work. I guess it
imposes several constraints about how your system is layed out.

2009/9/22, Frank <frank...@gmail.com>:
--
Inviato dal mio dispositivo mobile

Kyle Baley

unread,
Sep 22, 2009, 9:20:02 PM9/22/09
to sharp-arc...@googlegroups.com
I've used it with Oracle and ADO.NET and it requires other dependencies. Doesn't work out of the box like it does against a SQL Server database.
Reply all
Reply to author
Forward
0 new messages