SQL Azure瞬态错误与数据访问应用程序块6.0

时间:2014-05-26 06:16:33

标签: azure-sql-database enterprise-library

在我们的一个应用程序中,我们使用的是Enterprise Library 6.0数据访问块。我们正在将Database对象初始化为

DatabaseFactory.SetDatabaseProviderFactory(new DatabaseProviderFactory());
Database database = DatabaseFactory.CreateDatabase();

我们需要为上面的数据库对象设置 SqlAzureTransientErrorDetectionStrategy和/或RetryPolicy

有没有办法在数据访问应用程序块和适用于Windows Azure SQL的瞬态故障处理应用程序块?

我知道我们可以使用ReliableSqlConnection实现它,但找不到任何资源用于数据访问应用程序块&瞬态故障处理应用程序块。

1 个答案:

答案 0 :(得分:2)

更新开始

我在这里添加完整的类实现,以便它对其他用户也有用。

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 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。它主要用于支持联邦,但您可以修改它或只使用基本构造函数来处理注入重试策略

public SqlAzureDatabase(string connectionString)
           : this(connectionString, FederationType.None, null, null, null)
{
}