12
12
13
13
namespace Xtensive . Orm . Reprocessing . Tests . ReprocessingContext
14
14
{
15
- public class Context
15
+ public class Context : IDisposable
16
16
{
17
17
private readonly Domain domain ;
18
+
18
19
public int Count ;
19
20
private AutoResetEvent wait1 = new AutoResetEvent ( false ) ;
20
21
private AutoResetEvent wait2 = new AutoResetEvent ( false ) ;
21
22
22
- public void Deadlock ( bool first , IsolationLevel ? isolationLevel , TransactionOpenMode ? transactionOpenMode )
23
+ public bool Disposed { get ; private set ; }
24
+
25
+ /// <summary>
26
+ /// Root runner.
27
+ /// </summary>
28
+ public void Run (
29
+ IsolationLevel ? isolationLevel ,
30
+ TransactionOpenMode ? transactionOpenMode ,
31
+ Action < bool , IsolationLevel ? , TransactionOpenMode ? > action )
23
32
{
24
- TestContext . WriteLine ( "Context.DeadLock entered" ) ;
25
- domain . WithStrategy ( ExecuteActionStrategy . HandleUniqueConstraintViolation ) . WithIsolationLevel ( isolationLevel . GetValueOrDefault ( IsolationLevel . RepeatableRead ) ) . WithTransactionOpenMode ( transactionOpenMode . GetValueOrDefault ( TransactionOpenMode . New ) ) . Execute (
33
+ domain . Execute (
26
34
session => {
35
+ session . Remove ( session . Query . All < Foo > ( ) ) ;
36
+ session . Remove ( session . Query . All < Bar > ( ) ) ;
37
+ session . Remove ( session . Query . All < Bar2 > ( ) ) ;
38
+ _ = new Bar ( session ) ;
39
+ _ = new Foo ( session ) ;
40
+ } ) ;
41
+
42
+ Parallel . Invoke (
43
+ ( ) => action ( true , isolationLevel , transactionOpenMode ) ,
44
+ ( ) => action ( false , isolationLevel , transactionOpenMode ) ) ;
45
+ }
46
+
47
+ #region Actions
48
+
49
+ // The actions that can be passed to root runner method (Run)
50
+ // Some might be wrapped by other actons,
51
+ // others used only directrly from runner method
52
+
53
+ public void Deadlock ( bool first , IsolationLevel ? isolationLevel , TransactionOpenMode ? transactionOpenMode )
54
+ {
55
+ domain . WithStrategy ( ExecuteActionStrategy . HandleUniqueConstraintViolation )
56
+ . WithIsolationLevel ( isolationLevel . GetValueOrDefault ( IsolationLevel . RepeatableRead ) )
57
+ . WithTransactionOpenMode ( transactionOpenMode . GetValueOrDefault ( TransactionOpenMode . New ) )
58
+ . Execute ( session => {
27
59
_ = Interlocked . Increment ( ref Count ) ;
28
60
_ = new Bar2 ( session , DateTime . Now , Guid . NewGuid ( ) ) { Name = Guid . NewGuid ( ) . ToString ( ) } ;
29
61
if ( first ) {
30
62
_ = session . Query . All < Foo > ( ) . Lock ( LockMode . Exclusive , LockBehavior . Wait ) . ToArray ( ) ;
31
63
if ( wait1 != null ) {
32
64
_ = wait1 . Set ( ) ;
33
65
_ = wait2 . WaitOne ( ) ;
66
+ wait1 . Dispose ( ) ;
34
67
wait1 = null ;
35
68
}
36
69
_ = session . Query . All < Bar > ( ) . Lock ( LockMode . Exclusive , LockBehavior . Wait ) . ToArray ( ) ;
@@ -40,12 +73,12 @@ public void Deadlock(bool first, IsolationLevel? isolationLevel, TransactionOpen
40
73
if ( wait2 != null ) {
41
74
_ = wait2 . Set ( ) ;
42
75
_ = wait1 . WaitOne ( ) ;
76
+ wait2 . Dispose ( ) ;
43
77
wait2 = null ;
44
78
}
45
79
_ = session . Query . All < Foo > ( ) . Lock ( LockMode . Exclusive , LockBehavior . Wait ) . ToArray ( ) ;
46
80
}
47
81
} ) ;
48
- TestContext . WriteLine ( "Context.DeadLock left" ) ;
49
82
}
50
83
51
84
public void External (
@@ -54,7 +87,6 @@ public void External(
54
87
TransactionOpenMode ? transactionOpenMode ,
55
88
Action < Session , bool , IsolationLevel ? , TransactionOpenMode ? > action )
56
89
{
57
- TestContext . WriteLine ( "Context.External entered" ) ;
58
90
using ( var session = domain . OpenSession ( ) )
59
91
using ( var tran = isolationLevel == null ? null : session . OpenTransaction ( ) ) {
60
92
if ( tran != null ) {
@@ -76,7 +108,6 @@ public void External(
76
108
tran . Complete ( ) ;
77
109
}
78
110
}
79
- TestContext . WriteLine ( "Context.External left" ) ;
80
111
}
81
112
82
113
public void Parent (
@@ -86,7 +117,6 @@ public void Parent(
86
117
IExecuteActionStrategy strategy ,
87
118
Action < bool , IsolationLevel ? , TransactionOpenMode ? > action )
88
119
{
89
- TestContext . WriteLine ( "Context.Parent1 entered" ) ;
90
120
domain . WithStrategy ( strategy )
91
121
. WithIsolationLevel ( isolationLevel . GetValueOrDefault ( IsolationLevel . RepeatableRead ) )
92
122
. WithTransactionOpenMode ( transactionOpenMode . GetValueOrDefault ( TransactionOpenMode . New ) )
@@ -106,7 +136,6 @@ public void Parent(
106
136
}
107
137
action ( first , isolationLevel , transactionOpenMode ) ;
108
138
} ) ;
109
- TestContext . WriteLine ( "Context.Parent1 left" ) ;
110
139
}
111
140
112
141
public void Parent (
@@ -117,7 +146,6 @@ public void Parent(
117
146
IExecuteActionStrategy strategy ,
118
147
Action < bool , IsolationLevel ? , TransactionOpenMode ? > action )
119
148
{
120
- TestContext . WriteLine ( "Context.Parent2 entered" ) ;
121
149
domain . WithStrategy ( strategy )
122
150
. WithSession ( session )
123
151
. WithIsolationLevel ( isolationLevel . GetValueOrDefault ( IsolationLevel . RepeatableRead ) )
@@ -138,38 +166,15 @@ public void Parent(
138
166
}
139
167
action ( first , isolationLevel , transactionOpenMode ) ;
140
168
} ) ;
141
- TestContext . WriteLine ( "Context.Parent2 left" ) ;
142
- }
143
-
144
- public void Run (
145
- IsolationLevel ? isolationLevel ,
146
- TransactionOpenMode ? transactionOpenMode ,
147
- Action < bool , IsolationLevel ? , TransactionOpenMode ? > action )
148
- {
149
- TestContext . WriteLine ( "Context.Run entered" ) ;
150
- domain . Execute (
151
- session => {
152
- session . Remove ( session . Query . All < Foo > ( ) ) ;
153
- session . Remove ( session . Query . All < Bar > ( ) ) ;
154
- session . Remove ( session . Query . All < Bar2 > ( ) ) ;
155
- _ = new Bar ( session ) ;
156
- _ = new Foo ( session ) ;
157
- } ) ;
158
- TestContext . WriteLine ( "Context.Run executed Domain.Execute" ) ;
159
- TestContext . WriteLine ( "Context.Run Parallel.Invoke started" ) ;
160
- Parallel . Invoke (
161
- ( ) => action ( true , isolationLevel , transactionOpenMode ) ,
162
- ( ) => action ( false , isolationLevel , transactionOpenMode ) ) ;
163
- TestContext . WriteLine ( "Context.Run Parallel.Invoke ended" ) ;
164
- TestContext . WriteLine ( "Context.Run left" ) ;
165
169
}
166
170
167
171
public void UniqueConstraintViolation (
168
172
bool first , IsolationLevel ? isolationLevel , TransactionOpenMode ? transactionOpenMode )
169
173
{
170
- TestContext . WriteLine ( "Context.UniqueConstraintViolation entered" ) ;
171
- domain . WithStrategy ( ExecuteActionStrategy . HandleUniqueConstraintViolation ) . WithIsolationLevel ( isolationLevel . GetValueOrDefault ( IsolationLevel . RepeatableRead ) ) . WithTransactionOpenMode ( transactionOpenMode . GetValueOrDefault ( TransactionOpenMode . New ) ) . Execute (
172
- session => {
174
+ domain . WithStrategy ( ExecuteActionStrategy . HandleUniqueConstraintViolation )
175
+ . WithIsolationLevel ( isolationLevel . GetValueOrDefault ( IsolationLevel . RepeatableRead ) )
176
+ . WithTransactionOpenMode ( transactionOpenMode . GetValueOrDefault ( TransactionOpenMode . New ) )
177
+ . Execute ( session => {
173
178
_ = Interlocked . Increment ( ref Count ) ;
174
179
session . EnsureTransactionIsStarted ( ) ;
175
180
_ = new Bar2 ( session , DateTime . Now , Guid . NewGuid ( ) ) { Name = Guid . NewGuid ( ) . ToString ( ) } ;
@@ -179,27 +184,29 @@ public void UniqueConstraintViolation(
179
184
if ( wait1 != null && wait2 != null ) {
180
185
_ = wait1 . Set ( ) ;
181
186
_ = wait2 . WaitOne ( ) ;
187
+ wait1 . Dispose ( ) ;
182
188
wait1 = null ;
183
189
}
184
190
}
185
191
else if ( wait2 != null && wait2 != null ) {
186
192
_ = wait2 . Set ( ) ;
187
193
_ = wait1 . WaitOne ( ) ;
194
+ wait2 . Dispose ( ) ;
188
195
wait2 = null ;
189
196
}
190
197
_ = new Foo ( session ) { Name = name } ;
191
198
}
192
199
session . SaveChanges ( ) ;
193
200
} ) ;
194
- TestContext . WriteLine ( "Context.UniqueConstraintViolation left" ) ;
195
201
}
196
202
197
203
public void UniqueConstraintViolationPrimaryKey (
198
204
bool first , IsolationLevel ? isolationLevel , TransactionOpenMode ? transactionOpenMode )
199
205
{
200
- TestContext . WriteLine ( "Context.UniqueConstraintViolationPrimaryKey entered" ) ;
201
- domain . WithStrategy ( ExecuteActionStrategy . HandleUniqueConstraintViolation ) . WithIsolationLevel ( isolationLevel . GetValueOrDefault ( IsolationLevel . RepeatableRead ) ) . WithTransactionOpenMode ( transactionOpenMode . GetValueOrDefault ( TransactionOpenMode . New ) ) . Execute (
202
- session => {
206
+ domain . WithStrategy ( ExecuteActionStrategy . HandleUniqueConstraintViolation )
207
+ . WithIsolationLevel ( isolationLevel . GetValueOrDefault ( IsolationLevel . RepeatableRead ) )
208
+ . WithTransactionOpenMode ( transactionOpenMode . GetValueOrDefault ( TransactionOpenMode . New ) )
209
+ . Execute ( session => {
203
210
_ = Interlocked . Increment ( ref Count ) ;
204
211
session . EnsureTransactionIsStarted ( ) ;
205
212
_ = new Bar2 ( session , DateTime . Now , Guid . NewGuid ( ) ) { Name = Guid . NewGuid ( ) . ToString ( ) } ;
@@ -211,25 +218,36 @@ public void UniqueConstraintViolationPrimaryKey(
211
218
if ( w1 != null && w2 != null ) {
212
219
_ = w1 . Set ( ) ;
213
220
_ = w2 . WaitOne ( ) ;
221
+ wait1 . Dispose ( ) ;
214
222
wait1 = null ;
215
223
}
216
224
}
217
225
else if ( w1 != null && w2 != null ) {
218
226
_ = w2 . Set ( ) ;
219
227
_ = w1 . WaitOne ( ) ;
228
+ wait2 . Dispose ( ) ;
220
229
wait2 = null ;
221
230
}
222
231
_ = new Foo ( session , id ) { Name = Guid . NewGuid ( ) . ToString ( ) } ;
223
232
}
224
233
session . SaveChanges ( ) ;
225
234
} ) ;
226
- TestContext . WriteLine ( "Context.UniqueConstraintViolationPrimaryKey left" ) ;
227
235
}
236
+ #endregion
228
237
229
238
public Context ( Domain domain )
230
239
{
231
240
this . domain = domain ;
232
241
}
242
+
243
+ public void Dispose ( )
244
+ {
245
+ if ( Disposed )
246
+ return ;
247
+ Disposed = true ;
248
+ wait1 ? . Dispose ( ) ;
249
+ wait2 ? . Dispose ( ) ;
250
+ }
233
251
}
234
252
}
235
253
0 commit comments