44using System . Transactions ;
55using log4net ;
66using log4net . Repository . Hierarchy ;
7+ using NHibernate . Cfg ;
8+ using NHibernate . Engine ;
79using NHibernate . Linq ;
810using NHibernate . Test . TransactionTest ;
911using NUnit . Framework ;
@@ -15,6 +17,7 @@ public class DistributedSystemTransactionFixture : SystemTransactionFixtureBase
1517 {
1618 private static readonly ILog _log = LogManager . GetLogger ( typeof ( DistributedSystemTransactionFixture ) ) ;
1719 protected override bool UseConnectionOnSystemTransactionPrepare => true ;
20+ protected override bool AutoJoinTransaction => true ;
1821
1922 protected override bool AppliesTo ( Dialect . Dialect dialect )
2023 => dialect . SupportsDistributedTransactions && base . AppliesTo ( dialect ) ;
@@ -463,6 +466,8 @@ public void CanUseSessionWithManyScopes(bool explicitFlush)
463466 using ( var tx = new TransactionScope ( ) )
464467 {
465468 ForceEscalationToDistributedTx . Escalate ( ) ;
469+ if ( ! AutoJoinTransaction )
470+ s . JoinTransaction ( ) ;
466471 // Acquire the connection
467472 var count = s . Query < Person > ( ) . Count ( ) ;
468473 Assert . That ( count , Is . EqualTo ( 0 ) , "Unexpected initial entity count." ) ;
@@ -471,6 +476,8 @@ public void CanUseSessionWithManyScopes(bool explicitFlush)
471476 // No dodge here please! Allow to check chaining usages do not fail.
472477 using ( var tx = new TransactionScope ( ) )
473478 {
479+ if ( ! AutoJoinTransaction )
480+ s . JoinTransaction ( ) ;
474481 s . Save ( new Person ( ) ) ;
475482
476483 ForceEscalationToDistributedTx . Escalate ( ) ;
@@ -486,12 +493,16 @@ public void CanUseSessionWithManyScopes(bool explicitFlush)
486493 using ( var tx = new TransactionScope ( ) )
487494 {
488495 ForceEscalationToDistributedTx . Escalate ( ) ;
496+ if ( ! AutoJoinTransaction )
497+ s . JoinTransaction ( ) ;
489498 var count = s . Query < Person > ( ) . Count ( ) ;
490499 Assert . That ( count , Is . EqualTo ( 1 ) , "Unexpected entity count after committed insert." ) ;
491500 tx . Complete ( ) ;
492501 }
493502 using ( new TransactionScope ( ) )
494503 {
504+ if ( ! AutoJoinTransaction )
505+ s . JoinTransaction ( ) ;
495506 s . Save ( new Person ( ) ) ;
496507
497508 ForceEscalationToDistributedTx . Escalate ( ) ;
@@ -513,6 +524,8 @@ public void CanUseSessionWithManyScopes(bool explicitFlush)
513524 using ( var tx = new TransactionScope ( ) )
514525 {
515526 ForceEscalationToDistributedTx . Escalate ( ) ;
527+ if ( ! AutoJoinTransaction )
528+ s . JoinTransaction ( ) ;
516529 var count = s . Query < Person > ( ) . Count ( ) ;
517530 Assert . That ( count , Is . EqualTo ( 1 ) , "Unexpected entity count after rollback-ed insert." ) ;
518531 tx . Complete ( ) ;
@@ -528,10 +541,12 @@ public void CanUseSessionOutsideOfScopeAfterScope(bool explicitFlush)
528541 // NpgsqlOperationInProgressException: The connection is already in state 'Executing'
529542 // Not much an issue since it is advised to not use ConnectionReleaseMode.OnClose.
530543 using ( var s = OpenSession ( ) )
531- //using (var s = Sfi. WithOptions().ConnectionReleaseMode(ConnectionReleaseMode.OnClose).OpenSession())
544+ //using (var s = WithOptions().ConnectionReleaseMode(ConnectionReleaseMode.OnClose).OpenSession())
532545 {
533546 using ( var tx = new TransactionScope ( ) )
534547 {
548+ if ( ! AutoJoinTransaction )
549+ s . JoinTransaction ( ) ;
535550 s . Save ( new Person ( ) ) ;
536551
537552 ForceEscalationToDistributedTx . Escalate ( ) ;
@@ -611,7 +626,7 @@ public void WhenCommittingItemsAfterSessionDisposalWillAddThemTo2ndLevelCache()
611626 const string notNullData = "test" ;
612627 using ( var tx = new TransactionScope ( ) )
613628 {
614- using ( var s = Sfi . OpenSession ( ) )
629+ using ( var s = OpenSession ( ) )
615630 {
616631 var person = new CacheablePerson { NotNullData = notNullData } ;
617632 s . Save ( person ) ;
@@ -646,7 +661,7 @@ public void WhenCommittingItemsAfterSessionDisposalWillAddThemTo2ndLevelCache()
646661 // entity to load, allowing the session to not use the connection at all.
647662 // Will fail if a transaction manager tries to enlist user supplied connection. Do
648663 // not add a transaction scope below.
649- using ( var s = Sfi . WithOptions ( ) . Connection ( connection ) . OpenSession ( ) )
664+ using ( var s = WithOptions ( ) . Connection ( connection ) . OpenSession ( ) )
650665 {
651666 CacheablePerson person = null ;
652667 Assert . DoesNotThrow ( ( ) => person = s . Load < CacheablePerson > ( id ) , "Failed loading entity from second level cache." ) ;
@@ -662,6 +677,8 @@ public void DoNotDeadlockOnAfterTransactionWait()
662677 using ( var tx = new TransactionScope ( ) )
663678 {
664679 ForceEscalationToDistributedTx . Escalate ( ) ;
680+ if ( ! AutoJoinTransaction )
681+ s . JoinTransaction ( ) ;
665682 s . Save ( new Person ( ) ) ;
666683
667684 s . Flush ( ) ;
@@ -680,6 +697,8 @@ public void EnforceConnectionUsageRulesOnTransactionCompletion()
680697 using ( var tx = new TransactionScope ( ) )
681698 {
682699 ForceEscalationToDistributedTx . Escalate ( ) ;
700+ if ( ! AutoJoinTransaction )
701+ s . JoinTransaction ( ) ;
683702 s . Save ( new Person ( ) ) ;
684703
685704 s . Flush ( ) ;
@@ -698,6 +717,17 @@ public void EnforceConnectionUsageRulesOnTransactionCompletion()
698717 Assert . That ( interceptor . AfterException , Is . TypeOf < HibernateException > ( ) ) ;
699718 }
700719
720+ [ Test ]
721+ public void AdditionalJoinDoesNotThrow ( )
722+ {
723+ using ( new TransactionScope ( ) )
724+ using ( var s = OpenSession ( ) )
725+ {
726+ ForceEscalationToDistributedTx . Escalate ( ) ;
727+ Assert . DoesNotThrow ( ( ) => s . JoinTransaction ( ) ) ;
728+ }
729+ }
730+
701731 private void DodgeTransactionCompletionDelayIfRequired ( )
702732 {
703733 if ( Sfi . ConnectionProvider . Driver . HasDelayedDistributedTransactionCompletion )
@@ -761,4 +791,33 @@ public class DistributedSystemTransactionWithoutConnectionFromPrepareFixture : D
761791 {
762792 protected override bool UseConnectionOnSystemTransactionPrepare => false ;
763793 }
794+
795+ [ TestFixture ]
796+ public class DistributedSystemTransactionWithoutAutoJoinTransaction : DistributedSystemTransactionFixture
797+ {
798+ protected override bool AutoJoinTransaction => false ;
799+
800+ protected override void Configure ( Configuration configuration )
801+ {
802+ base . Configure ( configuration ) ;
803+ DisableConnectionAutoEnlist ( configuration ) ;
804+ }
805+
806+ protected override bool AppliesTo ( ISessionFactoryImplementor factory )
807+ => base . AppliesTo ( factory ) && factory . ConnectionProvider . Driver . SupportsEnlistmentWhenAutoEnlistmentIsDisabled ;
808+
809+ [ Test ]
810+ public void SessionIsNotEnlisted ( )
811+ {
812+ using ( new TransactionScope ( ) )
813+ {
814+ ForceEscalationToDistributedTx . Escalate ( ) ;
815+ // Dodge the OpenSession override which call JoinTransaction by calling WithOptions().
816+ using ( var s = WithOptions ( ) . OpenSession ( ) )
817+ {
818+ Assert . That ( s . GetSessionImplementation ( ) . TransactionContext , Is . Null ) ;
819+ }
820+ }
821+ }
822+ }
764823}
0 commit comments