azure-sql-database - SQL Azure transient 故障与数据访问应用程序 block 6.0

标签 azure-sql-database enterprise-library

在我们的一个应用程序中,我们使用了 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/

相关文章:

c# - 使用企业库的优缺点

asp.net - Microsoft 企业应用程序 block 与 ASP.NET 提供程序模型的关系是什么?

sql-server - 无法为无法在数据库中进行身份验证的用户提供参数 PASSWORD

arrays - 为什么我不能在 T-SQL 中使用 JSON_ARRAY() 合并 2 行?

c# - Ajax webmethod 仅在第一次尝试时无法触发存储过程

c# - 使用 Sql Azure 的 Azure 应用服务上的 TransactionScope

c# - 无法安装 NuGet 包

.net - 使用 EntLib 日志记录应用程序 block 使用 auth/secure smtp 服务器发送电子邮件

.net - 存储过程中的表值参数获取执行权限被拒绝错误

azure - Azure 数据仓库可以位于 Azure SQL 弹性池内吗?