public class DbMasterSlaveCommandInterceptor1 : DbCommandInterceptor { private string masterConnectionString = ConfigurationManager.ConnectionStrings["masterConnectionString"].ToString(); private string slaveConnectionString = ConfigurationManager.ConnectionStrings["slaveConnectionString"].ToString(); public string MasterConnectionString { get { return this.masterConnectionString; } } public string SlaveConnectionString { get { return this.slaveConnectionString; } } public override void NonQueryExecuting(DbCommand command, DbCommandInterceptionContext<int> interceptionContext) { base.NonQueryExecuting(command, interceptionContext);//update,delete等写操作直接走主库 } public override void NonQueryExecuted(DbCommand command, DbCommandInterceptionContext<int> interceptionContext) { base.NonQueryExecuted(command, interceptionContext); command.Parameters.Clear(); } public override void ReaderExecuting(DbCommand command, DbCommandInterceptionContext<DbDataReader> interceptionContext) { this.UpdateToSlave(command, interceptionContext); base.ReaderExecuting(command, interceptionContext); } public override void ReaderExecuted(DbCommand command, DbCommandInterceptionContext<DbDataReader> interceptionContext) { base.ReaderExecuted(command, interceptionContext); command.Parameters.Clear(); } public override void ScalarExecuting(DbCommand command, DbCommandInterceptionContext<object> interceptionContext) { this.UpdateToSlave(command, interceptionContext); base.ScalarExecuting(command, interceptionContext); } public override void ScalarExecuted(DbCommand command, DbCommandInterceptionContext<object> interceptionContext) { base.ScalarExecuted(command, interceptionContext); command.Parameters.Clear(); } private void UpdateToSlave(DbCommand command, DbInterceptionContext interceptionContext) { if (command.CommandText.ToLower().StartsWith("insert", StringComparison.InvariantCultureIgnoreCase) == false) { // 判断当前会话是否处于分布式事务中 bool isDistributedTran = Transaction.Current != null && Transaction.Current.TransactionInformation.Status != TransactionStatus.Committed; foreach (var context in interceptionContext.DbContexts) { //判断该 context 是否处于普通数据库事务中 bool isDbTran = context.Database.CurrentTransaction != null; // 如果处于分布式事务或普通事务中,则“禁用”读写分离,处于事务中的所有读写操作都指向 Master string connectionString = isDistributedTran || isDbTran ? this.MasterConnectionString : this.SlaveConnectionString; if (command.Connection.State == ConnectionState.Open) { command.Connection.Close(); } command.Connection.ConnectionString = connectionString; command.Connection.Open(); } } } }
protected void Application_Start() { AreaRegistration.RegisterAllAreas(); WebApiConfig.Register(GlobalConfiguration.Configuration); FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters); RouteConfig.RegisterRoutes(RouteTable.Routes); DbInterception.Add(new DbMasterSlaveCommandInterceptor1());//开启主从模式 }
此处可以实现读写分离,一切都OK,唯一的问题就是从库上打开的链接不能自动close掉,不知有谁遇到过没?
你主动打开的连接。自己关掉就可以了吧。至于为什么没有关,也不是很清楚。