1
1
using System ;
2
+ using System . Collections ;
2
3
using System . Transactions ;
4
+ using NHibernate . Cfg ;
5
+ using NHibernate . Engine ;
6
+ using NHibernate . Engine . Transaction ;
7
+ using NHibernate . Transaction ;
3
8
using NUnit . Framework ;
4
9
5
10
namespace NHibernate . Test . NHSpecificTest . NH2176
6
11
{
7
12
[ TestFixture ]
8
13
public class Fixture : BugTestCase
9
14
{
15
+ protected override void Configure ( Configuration configuration )
16
+ {
17
+ configuration . SetProperty ( Cfg . Environment . TransactionStrategy , "NHibernate.Test.NHSpecificTest.NH2176.CustomAdoNetTransactionFactory, NHibernate.Test" ) ;
18
+ }
19
+
10
20
protected override void OnSetUp ( )
11
21
{
12
22
base . OnSetUp ( ) ;
@@ -73,4 +83,44 @@ public void MultipleConsecutiveTransactionScopesCanBeUsedInsideASingleSession()
73
83
}
74
84
}
75
85
}
86
+
87
+ // Unfortunately, cannot derive and override NHibernate impl, methods are not virtual.
88
+ public class CustomAdoNetTransactionFactory : ITransactionFactory
89
+ {
90
+ private readonly AdoNetTransactionFactory _adoNetTransactionFactory =
91
+ new AdoNetTransactionFactory ( ) ;
92
+
93
+ public void Configure ( IDictionary props ) { }
94
+
95
+ public ITransaction CreateTransaction ( ISessionImplementor session )
96
+ {
97
+ return new AdoTransaction ( session ) ;
98
+ }
99
+
100
+ public void EnlistInDistributedTransactionIfNeeded ( ISessionImplementor session )
101
+ {
102
+ // No enlistment. This disables automatic flushes before ambient transaction
103
+ // commits. Explicit Flush calls required.
104
+ }
105
+
106
+ public bool IsInDistributedActiveTransaction ( ISessionImplementor session )
107
+ {
108
+ // Avoid agressive connection release while a transaction is ongoing. Allow
109
+ // auto-flushes (flushes before queries on dirtied entities).
110
+ return System . Transactions . Transaction . Current != null ;
111
+ }
112
+
113
+ public void ExecuteWorkInIsolation ( ISessionImplementor session , IIsolatedWork work ,
114
+ bool transacted )
115
+ {
116
+ using ( var tx = new TransactionScope ( TransactionScopeOption . Suppress ) )
117
+ {
118
+ // instead of duplicating the logic, we suppress the DTC transaction
119
+ // and create our own transaction instead
120
+ _adoNetTransactionFactory . ExecuteWorkInIsolation ( session , work ,
121
+ transacted ) ;
122
+ tx . Complete ( ) ;
123
+ }
124
+ }
125
+ }
76
126
}
0 commit comments