Skip to content

Commit 4167c3f

Browse files
committed
Preparing RetryAction.RefreshParameters
1 parent 992f696 commit 4167c3f

File tree

5 files changed

+79
-49
lines changed

5 files changed

+79
-49
lines changed

DataAccess/DbAccess.cs

Lines changed: 45 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -23,9 +23,6 @@ public static bool AutoDeriveRefCursorParameters
2323
set { AutoDeriveRefCursorParameters = value; }
2424
}
2525

26-
private const int _MaxRetryCount = 2;
27-
private const int _IncreasingDelayRetry = 500; // Increases 500 milliseconds delay time for every retry.
28-
2926
private DbProviderFactory _ProviderFactory;
3027
private DbConnection _Connection;
3128
public DbConnection Connection
@@ -39,6 +36,13 @@ public DbConnection Connection
3936
}
4037
}
4138

39+
private enum RetryAction
40+
{
41+
None = 0,
42+
Reconnect = 1,
43+
RefreshParameters = 2
44+
}
45+
4246
#region Constructors
4347

4448
public DbAccess(DbProviderFactory dbProviderFactory, string connectionString)
@@ -90,22 +94,49 @@ private DbCommand CreateCommand(string commandText, int commandTimeout, CommandT
9094

9195
private DbDataReader CreateReader(string commandText, int commandTimeout, CommandType commandType, Action<DbParameterBuilder> parametersBuilder, int resultSetCnt = 1)
9296
{
93-
for (int retry = 0; ; retry++)
97+
int recordsAffected;
98+
return InternalExecute(commandText, commandTimeout, commandType, parametersBuilder, resultSetCnt, out recordsAffected);
99+
}
100+
101+
private DbDataReader InternalExecute(string commandText, int commandTimeout, CommandType commandType, Action<DbParameterBuilder> parametersBuilder, int resultSetCnt, out int recordsAffected)
102+
{
103+
for (int retry = 2; ; retry--)
94104
{
95105
try
96106
{
97107
DbCommand dbCmd = CreateCommand(commandText, commandTimeout, commandType, parametersBuilder);
98108

99-
OnReaderExecuting(dbCmd, resultSetCnt);
100-
101-
return dbCmd.ExecuteReader();
109+
if (resultSetCnt > 0)
110+
{
111+
OnReaderExecuting(dbCmd, resultSetCnt);
112+
recordsAffected = -1;
113+
return dbCmd.ExecuteReader();
114+
}
115+
else
116+
{
117+
recordsAffected = dbCmd.ExecuteNonQuery();
118+
return null;
119+
}
102120
}
103121
catch (Exception e)
104122
{
105-
if (retry < _MaxRetryCount && OnConnectionLost(e))
106-
ReConnect(retry);
107-
else
123+
if (retry <= 0)
108124
throw;
125+
126+
switch (OnContextLost(e))
127+
{
128+
case RetryAction.Reconnect:
129+
ReConnect();
130+
break;
131+
case RetryAction.RefreshParameters:
132+
if (commandType == CommandType.StoredProcedure)
133+
RefreshStoredProcedureParameters(commandText);
134+
else
135+
throw;
136+
break;
137+
default:
138+
throw;
139+
}
109140
}
110141
}
111142
}
@@ -235,25 +266,11 @@ public void ExecuteMultiReader(string commandText, Action<DbParameterBuilder> pa
235266

236267
public int ExecuteNonQuery(string commandText, int commandTimeout, CommandType commandType, Action<DbParameterBuilder> parametersBuilder)
237268
{
238-
int nAffectedRows = 0;
269+
int recordsAffected;
239270

240-
for (int retry = 0; ; retry++)
241-
{
242-
try
243-
{
244-
nAffectedRows = CreateCommand(commandText, commandTimeout, commandType, parametersBuilder).ExecuteNonQuery();
245-
break;
246-
}
247-
catch (Exception e)
248-
{
249-
if (retry < _MaxRetryCount && OnConnectionLost(e))
250-
ReConnect(retry);
251-
else
252-
throw;
253-
}
254-
}
271+
InternalExecute(commandText, commandTimeout, commandType, parametersBuilder, 0, out recordsAffected);
255272

256-
return nAffectedRows;
273+
return recordsAffected;
257274
}
258275

259276
public int ExecuteNonQuery(string commandText, Action<DbParameterBuilder> parametersBuilder = null)
@@ -263,16 +280,12 @@ public int ExecuteNonQuery(string commandText, Action<DbParameterBuilder> parame
263280

264281
#endregion
265282

266-
private void ReConnect(int retrying)
283+
private void ReConnect()
267284
{
268285
if (_Connection != null)
269286
if (_Connection.State != ConnectionState.Closed)
270287
{
271288
_Connection.Close();
272-
273-
if (retrying > 0)
274-
Thread.Sleep(retrying * _IncreasingDelayRetry); // retrying starts at 0, increases delay time for every retry.
275-
276289
_Connection.Open();
277290
}
278291
}

DataAccess/DbAccess.slot.cs

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -5,20 +5,20 @@ namespace DbParallel.DataAccess
55
{
66
partial class DbAccess
77
{
8-
partial void OnOracleConnectionLost(Exception dbException, ref bool canRetry, ref bool processed);
9-
partial void OnSqlConnectionLost(Exception dbException, ref bool canRetry, ref bool processed);
10-
private bool OnConnectionLost(Exception dbException)
8+
partial void OnOracleContextLost(Exception dbException, ref RetryAction retryAction, ref bool processed);
9+
partial void OnSqlContextLost(Exception dbException, ref RetryAction retryAction, ref bool processed);
10+
private RetryAction OnContextLost(Exception dbException)
1111
{
12-
bool canRetry = false;
12+
RetryAction retryAction = RetryAction.None;
1313
bool hasBeenProcessed = false;
1414

1515
if (_TransactionManager.Transaction == null)
1616
{
17-
OnOracleConnectionLost(dbException, ref canRetry, ref hasBeenProcessed);
18-
OnSqlConnectionLost(dbException, ref canRetry, ref hasBeenProcessed);
17+
OnOracleContextLost(dbException, ref retryAction, ref hasBeenProcessed);
18+
OnSqlContextLost(dbException, ref retryAction, ref hasBeenProcessed);
1919
}
2020

21-
return canRetry;
21+
return retryAction;
2222
}
2323

2424
partial void OnOracleReaderExecuting(DbCommand dbCmd, int resultSetCnt/* = 1 */, ref bool processed);

DataAccess/Oracle/DbAccess.partial.cs

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ namespace DbParallel.DataAccess
1616
{
1717
partial class DbAccess
1818
{
19-
partial void OnOracleConnectionLost(Exception dbException, ref bool canRetry, ref bool processed)
19+
partial void OnOracleContextLost(Exception dbException, ref RetryAction retryAction, ref bool processed)
2020
{
2121
if (processed)
2222
return;
@@ -26,14 +26,24 @@ partial void OnOracleConnectionLost(Exception dbException, ref bool canRetry, re
2626
OracleException e = dbException as OracleException;
2727

2828
if (e == null)
29-
canRetry = false;
29+
retryAction = RetryAction.None;
3030
else
3131
switch (e.Number)
3232
{
3333
case 3113:
34-
case 4068: canRetry = true; break;
34+
case 4068:
35+
retryAction = RetryAction.Reconnect;
36+
break;
37+
case 6550:
38+
if (e.Errors.Count == 1 && e.Message.Contains("PLS-00306: "))
39+
retryAction = RetryAction.RefreshParameters;
40+
else
41+
retryAction = RetryAction.None;
42+
break;
3543
// To add other cases
36-
default: canRetry = false; break;
44+
default:
45+
retryAction = RetryAction.None;
46+
break;
3747
}
3848

3949
processed = true;

DataAccess/Properties/AssemblyInfo.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,5 +32,5 @@
3232
// You can specify all the values or you can default the Build and Revision Numbers
3333
// by using the '*' as shown below:
3434
// [assembly: AssemblyVersion("1.0.*")]
35-
[assembly: AssemblyVersion("1.8.1.5")]
36-
[assembly: AssemblyFileVersion("1.8.1.5")]
35+
[assembly: AssemblyVersion("1.8.2.0")]
36+
[assembly: AssemblyFileVersion("1.8.2.0")]

DataAccess/SqlServer/DbAccess.partial.cs

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ namespace DbParallel.DataAccess
55
{
66
partial class DbAccess
77
{
8-
partial void OnSqlConnectionLost(Exception dbException, ref bool canRetry, ref bool processed)
8+
partial void OnSqlContextLost(Exception dbException, ref RetryAction retryAction, ref bool processed)
99
{
1010
if (processed)
1111
return;
@@ -15,14 +15,21 @@ partial void OnSqlConnectionLost(Exception dbException, ref bool canRetry, ref b
1515
SqlException e = dbException as SqlException;
1616

1717
if (e == null)
18-
canRetry = false;
18+
retryAction = RetryAction.None;
1919
else
2020
switch (e.Number)
2121
{
2222
case 233:
23-
case -2: canRetry = true; break;
23+
case -2:
24+
retryAction = RetryAction.Reconnect;
25+
break;
26+
case 201:
27+
case 8144:
28+
retryAction = RetryAction.RefreshParameters;
29+
break;
2430
// To add other cases
25-
default: canRetry = false; break;
31+
default: retryAction = RetryAction.None;
32+
break;
2633
}
2734

2835
processed = true;

0 commit comments

Comments
 (0)