///

///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拦截器来实现数据库读写分离~终结~配置的优化和事务里读写的统一...相关推荐

  1. ef mysql自动更新_EF Core中怎么实现自动更新实体的属性值到数据库

    我们在开发系统的时候,经常会遇到这种需求数据库表中的行被更新时需要自动更新某些列. 数据库 比如下面的Person表有一列UpdateTime,这列数据要求在行被更新后自动更新为系统的当前时间. Pe ...

  2. EF mysql 数据迁移_EF Code First Migrations数据库迁移

    1.EF Code First创建数据库 新建控制台应用程序Portal,通过程序包管理器控制台添加EntityFramework. 在程序包管理器控制台中执行以下语句,安装EntityFramewo ...

  3. mysql 数据拦截器_拦截器中操作数据库

    做了个小项目,当初设计的是只有一个模块的用户行为被记录,其他不用记录,昨天突然说,要用户在整个系统的行为都要被记录. 很懵逼,如果把用户行为的记录放在各个模块,可以很精确的记录,但是各个模块都要有更改 ...

  4. Redis 读写分离技术架构解析

    以下文章来源方志朋的博客,回复"666"获面试宝典 Redis 不管主从版还是集群规格,replica作为备库不对外提供服务,只有在发生HA的时候,replica提升为master ...

  5. Redis读写分离技术架构解析

    作者:小热爱 来源:juejin.cn/post/6955355686108659726 背景 Redis 不管主从版还是集群规格,replica作为备库不对外提供服务,只有在发生HA的时候,repl ...

  6. Shopee ClickHouse 冷热数据分离存储架构与实践

    本文首发于微信公众号"Shopee技术团队". 摘要 Shopee ClickHouse 是一款基于开源数据库 ClickHouse 做二次开发.架构演进的高可用分布式分析型数据库 ...

  7. ssm 新建拦截器_拦截器在springboot项目和ssm架构项目的应用

    1.拦截器的主要功能 在访问某节点url前拦截客户端发来的请求,判断该请求是否符合自己定义的要求,如果不符合,返回false,该节点url的对应代码不会被执行:如果符合,返回true,可以执行该节点u ...

  8. ef mysql 读写分离_基于 EntityFramework 的数据库主从读写分离服务插件

    基于 EntityFramework 的数据库主从读写分离服务插件 1. 版本信息和源码 1.1版本信息 v1.01 beta(2015-04-07),基于 EF 6.1 开发,支持 EF 6.1 之 ...

  9. 高可用Mysql架构_Mysql主从复制、Mysql双主热备、Mysql双主双从、Mysql读写分离(Mycat中间件)、Mysql分库分表架构(Mycat中间件)的演变...

    [Mysql主从复制] 解决的问题 数据分布:比如一共150台机器,分别往电信.网通.移动各放50台,这样无论在哪个网络访问都很快.其次按照地域,比如国内国外,北方南方,这样地域性访问解决了. 负载均 ...

最新文章

  1. SharePoint2010沙盒解决方案基础开发——关于TreeView树形控件读取列表数据(树形导航)的webpart开发及问题...
  2. Web服务器 之 Apache 2.x 服务器中的URL重写的配置和应用
  3. 沭阳县依托运用大数据推进平安建设
  4. 第1次作业+105032014074
  5. 挂机脚本_叠猫猫逛店铺挂机脚本,每天稳定50次
  6. 初识Docker-Docker的安装
  7. 按下enter键禁止页面刷新
  8. Python基础入门6_文件和异常
  9. linux系统写一个脚本,编写一个简单的linuxshell脚本
  10. ClientScript.RegisterStartupScript 不起作用
  11. C++函数模板(模板函数)详解
  12. 线性代数(1):行列式和展开式
  13. ChainZ Arena攻略+全红卡评分
  14. verilog的时钟分频与时钟使能
  15. 给测试小姐姐的第三封信 | ORACLE存储过程知识分享和测试说明
  16. 这篇寒门博士论文致谢火了:回首望过去,可怜无数山...
  17. 字节面试官推荐的一份 Java 基础面试题!太顶了
  18. 北京杭州差距这么大?程序员在北京准点下班,在杭州12点在还加班
  19. 关于Libra的思考:金融服务是否应该开源?
  20. SUN Solaris10 安装配置NET-SNMP——方式2(pkg软件包)

热门文章

  1. 1562a检测软件_洛达1562a空间音频版评测!!!
  2. 【SpringBoot 2】(十)数据库相关
  3. LDAP命令介绍---dsreplication--enable:DISABLE
  4. Docker 网络命名空间
  5. 新手教程:不写JS,在MIP页中实现异步加载数据
  6. 常见的几种内排序算法以及实现(C语言)(转)
  7. 捧上天的AI落地困难,“ 不懂变通”的华为云如何应付?
  8. 【python】编程学习练习题-2
  9. 扩充swap空间的两种方法
  10. 两个精彩的比喻:吞吐量和延迟、信号量和互斥锁