1
- // Copyright (C) 2009-2020 Xtensive LLC.
1
+ // Copyright (C) 2009-2021 Xtensive LLC.
2
2
// This code is distributed under MIT license terms.
3
3
// See the License.txt file in the project root for more information.
4
4
// Created by: Denis Krjuchkov
@@ -38,20 +38,35 @@ public override DbParameter CreateParameter()
38
38
/// <inheritdoc/>
39
39
public override void Open ( )
40
40
{
41
- if ( ! checkConnectionIsAlive )
41
+ if ( ! checkConnectionIsAlive ) {
42
42
base . Open ( ) ;
43
- else
44
- OpenWithCheck ( DefaultCheckConnectionQuery ) ;
43
+ }
44
+ else {
45
+ var connectionHandlers = Extensions . Get < ConnectionHandlersExtension > ( ) ;
46
+ if ( connectionHandlers == null ) {
47
+ OpenWithCheckFast ( DefaultCheckConnectionQuery ) ;
48
+ }
49
+ else {
50
+ OpenWithCheckAndNotification ( DefaultCheckConnectionQuery , connectionHandlers ) ;
51
+ }
52
+ }
45
53
}
46
54
47
55
/// <inheritdoc/>
48
56
public override Task OpenAsync ( CancellationToken cancellationToken )
49
57
{
50
58
cancellationToken . ThrowIfCancellationRequested ( ) ;
51
- if ( ! checkConnectionIsAlive )
59
+ if ( ! checkConnectionIsAlive ) {
52
60
return base . OpenAsync ( cancellationToken ) ;
53
- else
54
- return OpenWithCheckAsync ( DefaultCheckConnectionQuery , cancellationToken ) ;
61
+ }
62
+
63
+ var connectionHandlers = Extensions . Get < ConnectionHandlersExtension > ( ) ;
64
+ if ( connectionHandlers == null ) {
65
+ return OpenWithCheckFastAsync ( DefaultCheckConnectionQuery , cancellationToken ) ;
66
+ }
67
+ else {
68
+ return OpenWithCheckAndNotificationAsync ( DefaultCheckConnectionQuery , connectionHandlers , cancellationToken ) ;
69
+ }
55
70
}
56
71
57
72
/// <inheritdoc/>
@@ -65,7 +80,13 @@ public override void OpenAndInitialize(string initializationScript)
65
80
var script = string . IsNullOrEmpty ( initializationScript . Trim ( ) )
66
81
? DefaultCheckConnectionQuery
67
82
: initializationScript ;
68
- OpenWithCheck ( script ) ;
83
+ var connectionHandlers = Extensions . Get < ConnectionHandlersExtension > ( ) ;
84
+ if ( connectionHandlers == null ) {
85
+ OpenWithCheckFast ( script ) ;
86
+ }
87
+ else {
88
+ OpenWithCheckAndNotification ( script , connectionHandlers ) ;
89
+ }
69
90
}
70
91
71
92
/// <inheritdoc/>
@@ -77,7 +98,10 @@ public override Task OpenAndInitializeAsync(string initializationScript, Cancell
77
98
var script = string . IsNullOrEmpty ( initializationScript . Trim ( ) )
78
99
? DefaultCheckConnectionQuery
79
100
: initializationScript ;
80
- return OpenWithCheckAsync ( script , cancellationToken ) ;
101
+ var connectionHandlers = Extensions . Get < ConnectionHandlersExtension > ( ) ;
102
+ return connectionHandlers == null
103
+ ? OpenWithCheckFastAsync ( script , cancellationToken )
104
+ : OpenWithCheckAndNotificationAsync ( script , connectionHandlers , cancellationToken ) ;
81
105
}
82
106
83
107
/// <inheritdoc/>
@@ -131,16 +155,16 @@ protected override void ClearActiveTransaction()
131
155
activeTransaction = null ;
132
156
}
133
157
134
- private void OpenWithCheck ( string checkQueryString )
158
+ private void OpenWithCheckFast ( string checkQueryString )
135
159
{
136
- bool connectionChecked = false ;
137
- bool restoreTriggered = false ;
160
+ var connectionChecked = false ;
161
+ var restoreTriggered = false ;
138
162
while ( ! connectionChecked ) {
139
163
base . Open ( ) ;
140
164
try {
141
165
using ( var command = underlyingConnection . CreateCommand ( ) ) {
142
166
command . CommandText = checkQueryString ;
143
- command . ExecuteNonQuery ( ) ;
167
+ _ = command . ExecuteNonQuery ( ) ;
144
168
}
145
169
connectionChecked = true ;
146
170
}
@@ -160,28 +184,118 @@ private void OpenWithCheck(string checkQueryString)
160
184
restoreTriggered = true ;
161
185
continue ;
162
186
}
163
- else
164
- throw ;
187
+
188
+ throw ;
165
189
}
166
190
}
167
191
}
168
192
169
- private async Task OpenWithCheckAsync ( string checkQueryString , CancellationToken cancellationToken )
193
+ private void OpenWithCheckAndNotification ( string checkQueryString , ConnectionHandlersExtension connectionHandlers )
170
194
{
171
- bool connectionChecked = false ;
172
- bool restoreTriggered = false ;
195
+ var connectionChecked = false ;
196
+ var restoreTriggered = false ;
197
+ var handlers = connectionHandlers . Handlers ;
198
+ while ( ! connectionChecked ) {
199
+ SqlHelper . NotifyConnectionOpening ( handlers , UnderlyingConnection , ( ! connectionChecked && ! restoreTriggered ) ) ;
200
+ underlyingConnection . Open ( ) ;
201
+ try {
202
+ SqlHelper . NotifyConnectionInitializing ( handlers , UnderlyingConnection , checkQueryString , ( ! connectionChecked && ! restoreTriggered ) ) ;
203
+ using ( var command = underlyingConnection . CreateCommand ( ) ) {
204
+ command . CommandText = checkQueryString ;
205
+ _ = command . ExecuteNonQuery ( ) ;
206
+ }
207
+ connectionChecked = true ;
208
+ SqlHelper . NotifyConnectionOpened ( handlers , UnderlyingConnection , ( ! connectionChecked && ! restoreTriggered ) ) ;
209
+ }
210
+ catch ( Exception exception ) {
211
+ SqlHelper . NotifyConnectionOpeningFailed ( handlers , UnderlyingConnection , exception , ( ! connectionChecked && ! restoreTriggered ) ) ;
212
+ if ( InternalHelpers . ShouldRetryOn ( exception ) ) {
213
+ if ( restoreTriggered ) {
214
+ throw ;
215
+ }
216
+
217
+ var newConnection = new SqlServerConnection ( underlyingConnection . ConnectionString ) ;
218
+ try {
219
+ underlyingConnection . Close ( ) ;
220
+ underlyingConnection . Dispose ( ) ;
221
+ }
222
+ catch { }
223
+
224
+ underlyingConnection = newConnection ;
225
+ restoreTriggered = true ;
226
+ continue ;
227
+ }
228
+
229
+ throw ;
230
+ }
231
+ }
232
+ }
233
+
234
+ private async Task OpenWithCheckFastAsync ( string checkQueryString , CancellationToken cancellationToken )
235
+ {
236
+ var connectionChecked = false ;
237
+ var restoreTriggered = false ;
173
238
174
239
while ( ! connectionChecked ) {
175
240
cancellationToken . ThrowIfCancellationRequested ( ) ;
176
241
await base . OpenAsync ( cancellationToken ) . ConfigureAwait ( false ) ;
177
242
try {
178
243
using ( var command = underlyingConnection . CreateCommand ( ) ) {
179
244
command . CommandText = checkQueryString ;
180
- await command . ExecuteNonQueryAsync ( cancellationToken ) . ConfigureAwait ( false ) ;
245
+ _ = await command . ExecuteNonQueryAsync ( cancellationToken ) . ConfigureAwait ( false ) ;
246
+ }
247
+ connectionChecked = true ;
248
+ }
249
+ catch ( Exception exception ) {
250
+ if ( InternalHelpers . ShouldRetryOn ( exception ) ) {
251
+ if ( restoreTriggered ) {
252
+ throw ;
253
+ }
254
+ var newConnection = new SqlServerConnection ( underlyingConnection . ConnectionString ) ;
255
+ try {
256
+ underlyingConnection . Close ( ) ;
257
+ underlyingConnection . Dispose ( ) ;
258
+ }
259
+ catch { }
260
+
261
+ underlyingConnection = newConnection ;
262
+ restoreTriggered = true ;
263
+ continue ;
264
+ }
265
+
266
+ throw ;
267
+ }
268
+ }
269
+ }
270
+
271
+ private async Task OpenWithCheckAndNotificationAsync ( string checkQueryString ,
272
+ ConnectionHandlersExtension connectionHandlers , CancellationToken cancellationToken )
273
+ {
274
+ var connectionChecked = false ;
275
+ var restoreTriggered = false ;
276
+ var handlers = connectionHandlers . Handlers ;
277
+
278
+ while ( ! connectionChecked ) {
279
+ cancellationToken . ThrowIfCancellationRequested ( ) ;
280
+
281
+ SqlHelper . NotifyConnectionOpening ( handlers , UnderlyingConnection , ! connectionChecked && ! restoreTriggered ) ;
282
+
283
+ await underlyingConnection . OpenAsync ( cancellationToken ) . ConfigureAwait ( false ) ;
284
+ try {
285
+ SqlHelper . NotifyConnectionInitializing ( handlers ,
286
+ UnderlyingConnection , checkQueryString , ! connectionChecked && ! restoreTriggered ) ;
287
+
288
+ using ( var command = underlyingConnection . CreateCommand ( ) ) {
289
+ command . CommandText = checkQueryString ;
290
+ _ = await command . ExecuteNonQueryAsync ( cancellationToken ) . ConfigureAwait ( false ) ;
181
291
}
182
292
connectionChecked = true ;
293
+ SqlHelper . NotifyConnectionOpened ( handlers , UnderlyingConnection , ! connectionChecked && ! restoreTriggered ) ;
183
294
}
184
295
catch ( Exception exception ) {
296
+ SqlHelper . NotifyConnectionOpeningFailed ( handlers ,
297
+ UnderlyingConnection , exception , ( ! connectionChecked && ! restoreTriggered ) ) ;
298
+
185
299
if ( InternalHelpers . ShouldRetryOn ( exception ) ) {
186
300
if ( restoreTriggered ) {
187
301
throw ;
@@ -197,8 +311,8 @@ private async Task OpenWithCheckAsync(string checkQueryString, CancellationToken
197
311
restoreTriggered = true ;
198
312
continue ;
199
313
}
200
- else
201
- throw ;
314
+
315
+ throw ;
202
316
}
203
317
}
204
318
}
0 commit comments