ef mysql 读写分离_EF架构~通过EF6的DbCommand拦截器来实现数据库读写分离~终结~配置的优化和事务里读写的统一...
///
///SQL命令攔截器///主要實現EF的讀寫分離///
public classCommandInterceptor : DbCommandInterceptor
{staticCommandInterceptor()
{
readConnList=DistributedReadWriteManager.Instance;
sysTimer.Enabled= true;
sysTimer.Elapsed+=sysTimer_Elapsed;
sysTimer.Start();
}///
///是否在一個事務中,如果是select,insert,update,delete都走主庫///ThreadStatic標識它只在當前線程有效///
[ThreadStatic]public static bool IsTransactionScope = false;///
///鎖住它///
private static object lockObj = new object();///
///定期找沒有在線的數據庫服務器///
private static Timer sysTimer = new Timer(5000);///
///讀庫,從庫集群,寫庫不用設置走默認的EF框架///
private static IListreadConnList;#region Private Methods
private static void sysTimer_Elapsed(objectsender, ElapsedEventArgs e)
{if (readConnList != null &&readConnList.Any())
{foreach (var item inreadConnList)
{//心跳測試,將死掉的服務器IP從列表中移除
var client = newTcpClient();try{
client.Connect(newIPEndPoint(IPAddress.Parse(item.Ip), item.Port));
}catch(SocketException)
{//異常,沒有連接上
readConnList.Remove(item);
}if (!client.Connected)
{
readConnList.Remove(item);
}
}
}
}///
///處理讀庫字符串///
///
private stringGetReadConn()
{if (readConnList != null &&readConnList.Any())
{var resultConn = readConnList[Convert.ToInt32(Math.Floor((double)new Random().Next(0, readConnList.Count)))];return string.Format(System.Configuration.ConfigurationManager.AppSettings["readDbConnection"]
, resultConn.Ip
, resultConn.DbName
, resultConn.UserId
, resultConn.Password);
}return string.Empty;
}///
///只讀庫的選擇,加工command對象///說明:事務中,所有語句都走主庫,事務外select走讀庫,insert,update,delete走主庫///希望:一個WEB請求中,讀與寫的倉儲使用一個,不需要在程序中去重新定義///
///
private voidReadDbSelect(DbCommand command)
{if (!string.IsNullOrWhiteSpace(GetReadConn()))//如果配置了讀寫分離,就去實現
{
command.Connection.Close();if (!command.CommandText.StartsWith("insert", StringComparison.InvariantCultureIgnoreCase) && !IsTransactionScope)
command.Connection.ConnectionString=GetReadConn();
command.Connection.Open();
}
}#endregion
#region Override Methods
///
///Linq to Entity生成的update,delete///
///
///
public override void NonQueryExecuting(DbCommand command, DbCommandInterceptionContextinterceptionContext)
{base.NonQueryExecuting(command, interceptionContext);//update,delete等寫操作直接走主庫
}///
///執行sql語句,并返回第一行第一列,沒有找到返回null,如果數據庫中值為null,則返回 DBNull.Value///
///
///
public override void ScalarExecuting(DbCommand command, DbCommandInterceptionContextinterceptionContext)
{
ReadDbSelect(command);base.ScalarExecuting(command, interceptionContext);
}///
///Linq to Entity生成的select,insert///發送到sqlserver之前觸發///warning:在select語句中DbCommand.Transaction為null,而ef會為每個insert添加一個DbCommand.Transaction進行包裹///
///
///
public override void ReaderExecuting(DbCommand command, DbCommandInterceptionContextinterceptionContext)
{
ReadDbSelect(command);base.ReaderExecuted(command, interceptionContext);
}///
///發送到sqlserver之后觸發///
///
///
public override void ReaderExecuted(DbCommand command, DbCommandInterceptionContextinterceptionContext)
{base.ReaderExecuted(command, interceptionContext);
}#endregion}
總結
以上是生活随笔為你收集整理的ef mysql 读写分离_EF架构~通过EF6的DbCommand拦截器来实现数据库读写分离~终结~配置的优化和事务里读写的统一...的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 一个事物两个方面的对比举例_顶管施工也有
- 下一篇: mysql5.5.20安装_mysql5