@@ -509,6 +509,48 @@ public void CanUseSessionOutsideOfScopeAfterScope([Values(false, true)] bool exp
509
509
}
510
510
}
511
511
512
+ [ Test ( Description = "Do not fail, but warn in case a delayed after scope disposal commit is made." ) ]
513
+ public void DelayedTransactionCompletion ( [ Values ( false , true ) ] bool explicitFlush )
514
+ {
515
+ for ( var i = 1 ; i <= 10 ; i ++ )
516
+ {
517
+ // Isolation level must be read committed on the control session: reading twice while expecting some data insert
518
+ // in between due to a late commit. Repeatable read would block and read uncommitted would see the uncommitted data.
519
+ using ( var controlSession = OpenSession ( ) )
520
+ using ( controlSession . BeginTransaction ( System . Data . IsolationLevel . ReadCommitted ) )
521
+ {
522
+ // We want to have the control session as ready to query as possible, thus beginning its
523
+ // transaction early for acquiring the connection, even if we will not use it before
524
+ // below scope completion.
525
+
526
+ using ( var tx = new TransactionScope ( ) )
527
+ {
528
+ using ( var s = OpenSession ( ) )
529
+ {
530
+ s . Save ( new Person { CreatedAt = DateTime . Today } ) ;
531
+
532
+ ForceEscalationToDistributedTx . Escalate ( ) ;
533
+
534
+ if ( explicitFlush )
535
+ s . Flush ( ) ;
536
+ }
537
+ tx . Complete ( ) ;
538
+ }
539
+
540
+ var count = controlSession . Query < Person > ( ) . Count ( ) ;
541
+ if ( count != i )
542
+ {
543
+ Thread . Sleep ( 100 ) ;
544
+ var countSecondTry = controlSession . Query < Person > ( ) . Count ( ) ;
545
+ Assert . Warn ( $ "Unexpected entity count: { count } instead of { i } . " +
546
+ "This may mean current data provider has a delayed commit, occurring after scope disposal. " +
547
+ $ "After waiting, count is now { countSecondTry } . ") ;
548
+ break ;
549
+ }
550
+ }
551
+ }
552
+ }
553
+
512
554
private void AssertNoPersons ( )
513
555
{
514
556
using ( var s = OpenSession ( ) )
0 commit comments