11using System . Linq ;
22using System . Transactions ;
3+ using NHibernate . Dialect ;
34using NHibernate . DomainModel . Northwind . Entities ;
45using NHibernate . Exceptions ;
56using NHibernate . Linq ;
@@ -10,7 +11,6 @@ namespace NHibernate.Test.Linq
1011{
1112 public class QueryLock : LinqTestCase
1213 {
13-
1414 [ Test ]
1515 public void CanSetLockLinqQueries ( )
1616 {
@@ -40,7 +40,6 @@ public void CanSetLockOnLinqPagingQuery()
4040 }
4141 }
4242
43-
4443 [ Test ]
4544 public void CanLockBeforeSkipOnLinqOrderedPageQuery ( )
4645 {
@@ -49,15 +48,14 @@ public void CanLockBeforeSkipOnLinqOrderedPageQuery()
4948 var result = ( from e in db . Customers
5049 orderby e . CompanyName
5150 select e )
52- . SetLockMode ( LockMode . Upgrade ) . Skip ( 5 ) . Take ( 5 ) . ToList ( ) ;
51+ . SetLockMode ( LockMode . Upgrade ) . Skip ( 5 ) . Take ( 5 ) . ToList ( ) ;
5352
5453 Assert . That ( result , Has . Count . EqualTo ( 5 ) ) ;
5554 Assert . That ( session . GetCurrentLockMode ( result [ 0 ] ) , Is . EqualTo ( LockMode . Upgrade ) ) ;
5655 AssertSeparateTransactionIsLockedOut ( result [ 0 ] . CustomerId ) ;
5756 }
5857 }
5958
60-
6159 private void AssertSeparateTransactionIsLockedOut ( string customerId )
6260 {
6361 using ( new TransactionScope ( TransactionScopeOption . Suppress ) )
@@ -68,14 +66,49 @@ private void AssertSeparateTransactionIsLockedOut(string customerId)
6866 Assert . Throws < GenericADOException > (
6967 ( ) =>
7068 {
71- var result2 = ( from e in s2 . Query < Customer > ( )
72- where e . CustomerId == customerId
73- select e ) . SetLockMode ( LockMode . UpgradeNoWait )
74- . Timeout ( 5 ) . ToList ( ) ;
75- Assert . IsNotNull ( result2 ) ;
76- } , "Expected an exception to indicate locking failure due to already locked." ) ;
69+ var result2 = (
70+ from e in s2 . Query < Customer > ( )
71+ where e . CustomerId == customerId
72+ select e
73+ ) . SetLockMode ( LockMode . UpgradeNoWait )
74+ . WithOptions ( o => o . SetTimeout ( 5 ) )
75+ . ToList ( ) ;
76+ Assert . That ( result2 , Is . Not . Null ) ;
77+ } ,
78+ "Expected an exception to indicate locking failure due to already locked." ) ;
7779 }
7880 }
81+
82+ [ Test ]
83+ [ Description ( "Verify that different lock modes are respected even if the query is otherwise exactly the same." ) ]
84+ public void CanChangeLockModeForQuery ( )
85+ {
86+ // Limit to a few dialects where we know the "nowait" keyword is used to make life easier.
87+ Assume . That ( Dialect is MsSql2000Dialect || Dialect is Oracle8iDialect || Dialect is PostgreSQL81Dialect ) ;
88+
89+ using ( session . BeginTransaction ( ) )
90+ {
91+ var result = BuildQueryableAllCustomers ( db . Customers , LockMode . Upgrade ) . ToList ( ) ;
92+ Assert . That ( result , Has . Count . EqualTo ( 91 ) ) ;
93+
94+ using ( var logSpy = new SqlLogSpy ( ) )
95+ {
96+ // Only difference in query is the lockmode - make sure it gets picked up.
97+ var result2 = BuildQueryableAllCustomers ( session . Query < Customer > ( ) , LockMode . UpgradeNoWait )
98+ . ToList ( ) ;
99+ Assert . That ( result2 , Has . Count . EqualTo ( 91 ) ) ;
100+
101+ Assert . That ( logSpy . GetWholeLog ( ) . ToLower ( ) , Does . Contain ( "nowait" ) ) ;
102+ }
103+ }
104+ }
105+
106+ private static IQueryable < Customer > BuildQueryableAllCustomers (
107+ IQueryable < Customer > dbCustomers ,
108+ LockMode lockMode )
109+ {
110+ return ( from e in dbCustomers select e ) . SetLockMode ( lockMode ) . WithOptions ( o => o . SetTimeout ( 5 ) ) ;
111+ }
79112 }
80113}
81114
0 commit comments