背景
我们的Sql Server数据库不能支持7*24h不停机,所以只能做双主热备,这就需要我们应用层在主数据库崩坏后自动切到备用数据库,等主数据库恢复好了以后再切回来。
实现
按照官方文档新建一个resolver类。
/// <summary>
/// 用这两个注解替换调ABP原本默认的connection string resolver
/// </summary>
[Dependency(ReplaceServices = true)]
[ExposeServices(typeof(IConnectionStringResolver))]
public class ConnectionResolver : IConnectionStringResolver, ITransientDependency
{
private readonly IConfiguration _configuration;
public ConnectionResolver(IConfiguration configuration)
{
_configuration = configuration;
}
/// <summary>
/// 这个方法在abp源码里已经标注为Obsolete,所以基本不会调用,但是继承IConnectionStringResolver接口需要实现它
/// </summary>
/// <param name="connectionStringName"></param>
/// <returns></returns>
public virtual string Resolve(string connectionStringName = null)
{
return ResolveAsync(connectionStringName).Result;
}
/// <summary>
/// 这也是接口强制实现的方法,ABP框架主要调用的是这个方法
/// </summary>
/// <param name="connectionStringName"></param>
/// <returns></returns>
public virtual Task<string> ResolveAsync(string connectionStringName = null)
{
var defaultConnection = _configuration.GetConnectionString("Default");
var secondConnection = _configuration.GetConnectionString("Second");
using var connection = new SqlConnection(defaultConnection);//用using释放connection
try
{
connection.Open();
if (connection.State == ConnectionState.Open)
{
connection.Close();//保险起见及时关闭connection
return Task.FromResult(defaultConnection);//如果连接成功则返回默认连接
}
else
{
return Task.FromResult(secondConnection);//如果连接失败则返回备选连接
}
}
catch (Exception)
{
return Task.FromResult(secondConnection);
}
}
}
这里参照ABP提供的依赖注入法,替代原来框架提供的DefaultConnectionStringResolver