session scope and transaction scope

83 views
Skip to first unread message

raghavsri

unread,
Aug 12, 2010, 3:11:05 AM8/12/10
to Castle Project Users
Hi .
I have seen example .. where some program uses
trasnsaction scope inside a session scope
some example uses session scope inside the transaction scope..

When to use what .. ex1 and ex2...?

ex1:
using(new SessionScope(FlushAction.Never))
{
using(TransactionScope tx = new
TransactionScope(OnDispose.Rollback))

ex2:

using(new TransactionScope ())
{
using(SessionScope(FlushAction.Never))


Thanks in advance..
Regards
Raghavendra

Martijn van Rheenen

unread,
Aug 12, 2010, 3:24:28 AM8/12/10
to castle-pro...@googlegroups.com
I was wondering about that too ;) Thanks for posting that question just a bit earlier than me...


--
You received this message because you are subscribed to the Google Groups "Castle Project Users" group.
To post to this group, send email to castle-pro...@googlegroups.com.
To unsubscribe from this group, send email to castle-project-u...@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/castle-project-users?hl=en.


Markus Zywitza

unread,
Aug 12, 2010, 7:44:53 AM8/12/10
to castle-pro...@googlegroups.com
Scopes are an infrastructure concern. The best bet is to use
SessionScope per web request. If you are working with a GUI,you should
rather use IConversation.

SessionScope uses an implicit transaction since AR 2.0, so you should
be fine with a single SessionScoep unless you need to rollback in
other cases than an exception. The default behaviour for
SessionScope's implicit transaction is to rollback on exceptions and
commit otherwise.

If you nest Scopes, only nest ONE TransactionScope with an inherited
transaction in ONE SessionScope and never put a SessionScope into a
TransactionScope. This is necessary if you use SessionScope on
infrastructure level and need to control committing.
Example: In a web app, SessionScope per request is used. Some
controllers need to rollback changes based on contextual data. You
should then use a TransactionScope with inherited transaction in the
controller method called.

The examples you have given are both antipatterns:

> ex1:
> using(new SessionScope(FlushAction.Never))
> {
>   using(TransactionScope tx = new
> TransactionScope(OnDispose.Rollback))

Here you have a session scope with a non-flushing implicit
transaction. You create a new session scope in the second using
statement that flushes on commit, but only if you call
tx.VoteCommit(). If you need this, leave the outer session scope out,
it is used only outside the inner scope.

> ex2:
>
> using(new TransactionScope ())
> {
>   using(SessionScope(FlushAction.Never))

You create a session with transaction in the outer scope. Then you use
a NEW session with implicit non-flushing transaction in the inner
scope, using the original session only outside of the inner scope.

Antipattern 3:
using (new SessionScope())
using (new TransactionScope())
{

}
The outer scope's session is never used.

Antipattern 4:
using (var tx1 = new TransactionScope())
{
using (var tx2 = new TransactionScope())
{
//...
}
}
NH sessions allow only one transaction per session. This nesting
creates therefore a new session with a new transaction. If you have
read-committed isolation and access an entity in the inner scope that
was already flushed in the outer scope, you'll get a deadlock.

-Markus

Reply all
Reply to author
Forward
0 new messages