在我们的一个应用程序中,我们使用了 Enterprise Library 6.0 数据访问 block 。我们将数据库对象初始化为
DatabaseFactory.SetDatabaseProviderFactory(new DatabaseProviderFactory());
Database database = DatabaseFactory.CreateDatabase();
我们需要为上述数据库对象设置 SqlAzureTransientErrorDetectionStrategy 和/或 RetryPolicy。
有没有什么方法可以使用 Windows Azure SQL 的数据访问应用程序 block 和 transient 故障处理应用程序 block 来完成上述工作?
我知道我们可以使用 ReliableSqlConnection 实现它,但找不到任何数据访问应用程序 block 和 transient 故障处理应用程序 block 的资源。
最佳答案
更新开始
我在这里添加了完整的类实现,这样它也对其他用户有用。
public class SqlAzureDatabase : SqlDatabase
{
public RetryPolicy _retryPolicy { get; set; }
public SqlAzureDatabase(string connectionString, RetryPolicy retryPolicy)
: base(connectionString)
{
this._retryPolicy = retryPolicy;
}
protected override DatabaseConnectionWrapper GetWrappedConnection()
{
return new DatabaseConnectionWrapper(GetNewOpenConnection());
}
private DbConnection GetNewOpenConnection()
{
SqlConnection connection = null;
try
{
connection = base.CreateConnection() as SqlConnection;
if (connection != null)
{
connection.OpenWithRetry(this._retryPolicy);
}
}
catch
{
if (connection != null && connection.State != System.Data.ConnectionState.Closed)
connection.Close();
throw;
}
return connection;
}
public override int ExecuteNonQuery(DbCommand command)
{
using (DatabaseConnectionWrapper wrapper = GetOpenConnection())
{
PrepareCommand(command, wrapper.Connection);
return DoExecuteNonQueryWithRetry(command);
}
}
private int DoExecuteNonQueryWithRetry(DbCommand command)
{
if (command == null) throw new ArgumentNullException("command");
SqlCommand sqlCommand = command as SqlCommand;
if (sqlCommand != null)
{
int rowsAffected = sqlCommand.ExecuteNonQueryWithRetry(this._retryPolicy);
return rowsAffected;
}
return 0;
}
public override IDataReader ExecuteReader(DbCommand command)
{
using (DatabaseConnectionWrapper wrapper = GetOpenConnection())
{
PrepareCommand(command, wrapper.Connection);
IDataReader realReader = DoExecuteReaderWithRetry(command, CommandBehavior.Default);
return CreateWrappedReader(wrapper, realReader);
}
}
private IDataReader DoExecuteReaderWithRetry(DbCommand command, CommandBehavior cmdBehavior)
{
if (command == null) throw new ArgumentNullException("command");
SqlCommand sqlCommand = command as SqlCommand;
if (sqlCommand != null)
{
IDataReader reader = sqlCommand.ExecuteReaderWithRetry(_retryPolicy);
return reader;
}
return null;
}
public override object ExecuteScalar(DbCommand command)
{
using (DatabaseConnectionWrapper wrapper = GetOpenConnection())
{
PrepareCommand(command, wrapper.Connection);
return DoExecuteScalarWithRetry(command);
}
}
private object DoExecuteScalarWithRetry(IDbCommand command)
{
if (command == null) throw new ArgumentNullException("command");
SqlCommand sqlCommand = command as SqlCommand;
if (sqlCommand != null)
{
object returnValue = sqlCommand.ExecuteScalarWithRetry(this._retryPolicy);
return returnValue;
}
return null;
}
}
SqlAzureDatabase 类的作用如下所述。
Database database = new SqlAzureDatabase(connectionString, retryPolicy);
更新结束
我有类似的需求,最终创建了 SqlDatabase
类的扩展并重写了 GetWrappedConnection
方法:
protected override DatabaseConnectionWrapper GetWrappedConnection()
{
return new DatabaseConnectionWrapper(GetNewOpenConnection());
}
GetNewOpenConnection() 是私有(private)方法
private DbConnection GetNewOpenConnection()
{
SqlConnection connection = null;
try
{
connection = CreateConnection() as SqlConnection;
if(connection != null)
{
connection.OpenWithRetry(this._retryPolicy);
}
//instrumentationProvider.FireConnectionOpenedEvent();
}
catch
{
if (connection != null)
connection.Close();
throw;
}
return connection;
}
下载 SqlAzureDatabase
类 @ http://1drv.ms/SJft8o .它主要是为了支持联合,但您可以修改它或只使用将负责注入(inject)重试策略的基本构造函数
public SqlAzureDatabase(string connectionString)
: this(connectionString, FederationType.None, null, null, null)
{
}
关于azure-sql-database - SQL Azure transient 故障与数据访问应用程序 block 6.0,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23863830/