Set => _underlyingSqlCommand.DesignTimeVisible = value Get => _underlyingSqlCommand.DesignTimeVisible Set => _underlyingSqlCommand.CommandType = value Get => _underlyingSqlCommand.CommandType Set => _underlyingSqlCommand.CommandTimeout = value Get => _underlyingSqlCommand.CommandTimeout Set => _underlyingSqlCommand.CommandText = value Get => _underlyingSqlCommand.CommandText Public ReliableSqlDbCommand(SqlCommand command, IRetryPolicy retryPolicy) Private readonly SqlCommand _underlyingSqlCommand If (_underlyingConnection.State = ConnectionState.Open)įollowing similar approach to DbCommand: public sealed class ReliableSqlDbCommand : DbCommand Since, we are instantiating SqlConnection whenever its asked for we also need to dispose it properly, following derived type dispose pattern as suggested by Microsoft: protected override void Dispose(bool disposing) Protected override DbCommand CreateDbCommand() => new ReliableSqlDbCommand(_underlyingConnection.CreateCommand(), _retryPolicy) ![]() Protected override DbTransaction BeginDbTransaction(IsolationLevel isolationLevel) => _underlyingConnection.BeginTransaction(isolationLevel) Public override void Close() => _underlyingConnection.Close() ![]() Public override void ChangeDatabase(string databaseName) => _underlyingConnection.ChangeDatabase(databaseName) Public override ConnectionState State => _underlyingConnection.State Public override string ServerVersion => _underlyingConnection.ServerVersion Public override string DataSource => _underlyingConnection.DataSource Public override string Database => _underlyingConnection.Database If (_underlyingConnection.State != ConnectionState.Open) Set => _underlyingConnection.ConnectionString = _connectionString = value _underlyingConnection = new SqlConnection(connectionString) Public ReliableSqlDbConnection(string connectionString, IRetryPolicy retryPolicy) Private readonly IRetryPolicy _retryPolicy Private readonly SqlConnection _underlyingConnection Now, somehow we need to inject this policy to SqlClient's con and cmd, need a sealed class which 'is-a' DbConnection (DAL endpoints will remain intact) and also 'has-a' DbConnection (mimic the operations but with retries): public sealed class ReliableSqlDbConnection : DbConnection Private readonly ISet _transientDbErrors = new HashSet(new ") Extension methods to IDbConnection takes care of wrapping policy around existing methods. Have implemented 2nd approach ^^: This decouples policies to be DI'ed to the existing repos. ![]() ![]() I've a below approach and sort of need an improvement over it. Similar to the ways of http clients resilience where policy is addedīy this: will've code changes to minimum, need not touch repos but only the startup. "configure a Policy in startup and auto-magically all DB calls viaĭapper become resilient (fall backs to their fault tolerant mechanism) But, is there a built-in way in dapper/some-other-approaches, where we can In both ways, I need to change all my 30+ repos. Public static Task GetAsync(this IDbConnection connection, object primaryKey, IAsyncPolicy policy) => return await _policy.ExecuteAsync(async () => GetAsync (.)) Provide custom overloads which accepts IAsyncPolicy param.Wrap all the existing DB calls with await _policy.ExecuteAsync OR.Tried with success: I've answered below a custom SqlResiliencyPolicy using Polly after some research and tailored it to the project.īut, what I seek: The present way (PFB answered), demands me to either Need to make all the existing repos (around 30+) fault tolerant to deadlock and recover from it with log and wait approach.
0 Comments
Leave a Reply. |
AuthorWrite something about yourself. No need to be fancy, just an overview. ArchivesCategories |