@@ -574,7 +574,7 @@ finally
574
574
575
575
<para >
576
576
If your application manages transactions through .NET APIs such as <literal >System.Transactions</literal > library
577
- while not using a compatible transaction factory (see <literal >transaction.factory_class</literal >)
577
+ while not using a compatible transaction factory (see <literal >transaction.factory_class</literal >
578
578
in <xref linkend =" configuration-optional" />), <literal >ConnectionReleaseMode.AfterTransaction</literal > may cause
579
579
NHibernate to open and close several connections during one transaction, leading to unnecessary overhead and
580
580
transaction promotion from local to distributed. Specifying <literal >ConnectionReleaseMode.OnClose</literal >
@@ -583,5 +583,92 @@ finally
583
583
584
584
</sect1 >
585
585
586
+ <sect1 id =" transactions-scopes" >
587
+ <title >Transaction scopes (System.Transactions)</title >
588
+
589
+ <para >
590
+ Instead of using NHibernate <literal >ITransaction</literal >, <literal >TransactionScope</literal >
591
+ can be used. Please do not use both simultaneously. Using <literal >TransactionScope</literal >
592
+ requires using a compatible transaction factory (see <literal >transaction.factory_class</literal >
593
+ in <xref linkend =" configuration-optional" />). The default transaction factory supports scopes.
594
+ </para >
595
+
596
+ <para >
597
+ When using <literal >TransactionScope</literal > with NHibernate, you need to be aware of following
598
+ points:
599
+ </para >
600
+
601
+ <itemizedlist >
602
+ <listitem >
603
+ <para >
604
+ The session will enlist with the first scope in which the session is used (or opened).
605
+ As of NHibernate v5.0, it will enlist its connection in the transaction regardless of
606
+ connection string <literal >Enlist</literal > setting. Prior to v5.0, it was relying on
607
+ that setting being considered <literal >true</literal >, and on acquiring the connection
608
+ within the scope.
609
+ </para >
610
+ <para >
611
+ Sub-scopes are not supported. The session will be enlisted in the first scope within
612
+ which it was used, until this scope is committed or rollback. If auto-enlistment is
613
+ enabled on the connection and the session used on others scopes than the one in which
614
+ it is currently enlisted, the connection may enlist in another scope, and the session
615
+ will then fail to use it.
616
+ </para >
617
+ <para >
618
+ As of NHibernate v5.0, session auto-enlistment can be disabled from the session builder
619
+ obtained with <literal >ISessionFactory.WithOptions()</literal >, using the
620
+ <literal >AutoJoinTransaction</literal > option. The connection may still enlist itself
621
+ if connection string <literal >Enlist</literal > setting is not <literal >false</literal >.
622
+ A session can explicitly join the current system transaction by calling
623
+ <literal >ISession.JoinTransaction()</literal >.
624
+ </para >
625
+ </listitem >
626
+ <listitem >
627
+ <para >
628
+ As of NHibernate v5.0, <literal >FlushMode.Commit</literal > requires the configuration setting
629
+ <literal >transaction.use_connection_on_system_events</literal > to be true for flushing
630
+ from transaction scope commit. Otherwise, it will be your responsibility to flush the session
631
+ before completing the scope.
632
+ </para >
633
+ <para >
634
+ Using <literal >transaction.use_connection_on_system_events</literal > can cause undesired
635
+ transaction promotions to distributed: it requires using a dedicated connection for flushing,
636
+ and it delays session disposal (if done inside the scope) to the scope disposal. If you want
637
+ to avoid this, set this setting to <literal >false</literal > and manually flush your sessions.
638
+ </para >
639
+ </listitem >
640
+ <listitem >
641
+ <para >
642
+ As of NHibernate v5.0, <literal >ConnectionReleaseMode.AfterTransaction</literal > has no more
643
+ by default an "immediate" effect with transaction scopes. Previously, it was releasing the
644
+ connection from transaction completion events. But this is not officially supported by
645
+ Microsoft and this can cause issues especially with distributed transactions.
646
+ </para >
647
+ <para >
648
+ Since v5.0, by default, the connection will be actually released after the scope disposal at the
649
+ first session usage involving a connection, or at the session closing, whichever come first.
650
+ Alternatively, you may <literal >Disconnect()</literal > the session. (Requires
651
+ <literal >Reconnect()</literal > before re-using the session.)
652
+ </para >
653
+ <para >
654
+ When using <literal >transaction.use_connection_on_system_events</literal >, if the session is
655
+ disposed within the scope, the connection releasing will still occurs from transaction
656
+ completion event.
657
+ </para >
658
+ </listitem >
659
+ <listitem >
660
+ <para >
661
+ As of NHibernate v5.0, using transaction scope and trying to use the session connection within
662
+ <literal >AfterTransactionCompletion</literal > is forbidden and will raise an exception.
663
+ If the setting <literal >transaction.use_connection_on_system_events</literal >
664
+ is <literal >false</literal >, it will forbid any connection usage from
665
+ <literal >BeforeTransactionCompletion</literal > event too, when this event is triggered by
666
+ a transaction scope commit or rollback.
667
+ </para >
668
+ </listitem >
669
+ </itemizedlist >
670
+
671
+ </sect1 >
672
+
586
673
</chapter >
587
674
0 commit comments