EF架构~通过EF6的SQL命名拦截器来实现数据库读写分离

回到目录

前几天看了一个基于sqlserver的负载均衡与读写分离的软件Moebius,实现的方式还是不错的,这使得用sqlserver数据库的同学时有机会对数据库进行更有效的优化了

看着人有做的东西,自己也想用EF来实现一个读写分离,所以就有了本篇文章,仓储大叔读写分离的思路是:

1  用sqlserver自带的发布、订阅实现主,从数据库的结构,同步这事由sql帮我们完成

2  配置文件建立几个供只读的数据库连接串

3  建立SQL命令拦截器

4  修改大叔的DbContextRepository基数,添加拦截行为

5  测试,搞定

有了上面的想法,咱就可以干事了,第一步不用说了,可以自己百度,从第2步说起

2  配置文件建立几个供只读的数据库连接串

    <!-- 只写-->
    <add name="backgroundEntities" connectionString="metadata=res://*/background.csdl|res://*/background.ssdl|res://*/background.msl;provider=System.Data.SqlClient;provider connection string=&quot;data source=.;initial catalog=background;persist security info=True;user id=sa;password=zzl123;multipleactiveresultsets=True;application name=EntityFramework&quot;" providerName="System.Data.EntityClient" />
    <!-- 只读-->
    <add name="backgroundEntitiesRead" connectionString="metadata=res://*/background.csdl|res://*/background.ssdl|res://*/background.msl;provider=System.Data.SqlClient;provider connection string=&quot;data source=.;initial catalog=background_Read1;persist security info=True;user id=sa;password=zzl123;multipleactiveresultsets=True;application name=EntityFramework&quot;" providerName="System.Data.EntityClient" />

3  建立SQL命令拦截器

 /// <summary>
    /// SQL命令拦截器
    /// </summary>
    public class NoLockInterceptor : DbCommandInterceptor
    {
        private static readonly Regex _tableAliasRegex =
            new Regex(@"(?<tableAlias>AS \[Extent\d+\](?! WITH \(NOLOCK\)))",
                RegexOptions.Multiline | RegexOptions.IgnoreCase);

        [ThreadStatic]
        public static bool SuppressNoLock;
        public override void NonQueryExecuting(DbCommand command, DbCommandInterceptionContext<int> interceptionContext)
        {
            string conn = command.Connection.ConnectionString;
            base.NonQueryExecuting(command, interceptionContext);
        }
        public override void ScalarExecuting(DbCommand command,
            DbCommandInterceptionContext<object> interceptionContext)
        {
            command.Connection.Close();
            command.Connection.ConnectionString = "data source=.;initial catalog=background_Read1;persist security info=True;user id=sa;password=zzl123;multipleactiveresultsets=True;application name=EntityFramework";
            command.Connection.Open();

            if (!SuppressNoLock)
            {
                command.CommandText =
                    _tableAliasRegex.Replace(command.CommandText, "${tableAlias} WITH (NOLOCK)");
            }
        }

        public override void ReaderExecuting(DbCommand command, DbCommandInterceptionContext<DbDataReader> interceptionContext)
        {
            command.Connection.Close();
            command.Connection.ConnectionString = "data source=.;initial catalog=background_Read1;persist security info=True;user id=sa;password=zzl123;multipleactiveresultsets=True;application name=EntityFramework";
            command.Connection.Open();
            if (!SuppressNoLock)
            {
                command.CommandText =
                    _tableAliasRegex.Replace(command.CommandText, "${tableAlias} WITH (NOLOCK)");
            }
        }
    }

4  修改大叔的DbContextRepository基数,添加拦截行为

  public DbContextRepository(IUnitOfWork db, Action<string> logger)
        {
            UnitWork = db;
            Db = (DbContext)db;
            Logger = logger;
            ((IObjectContextAdapter)Db).ObjectContext.CommandTimeout = 0;

            //SQL语句拦截器
            System.Data.Entity.Infrastructure.Interception.DbInterception.Add(new EntityFrameworks.Data.Core.Common.NoLockInterceptor());
            EntityFrameworks.Data.Core.Common.NoLockInterceptor.SuppressNoLock = true;
        }

5  大功造成,感谢阅读!

本文章代码没有全部展示,只是展示一种思想,希望可以给大家带来帮助。

回到目录

时间: 2024-10-07 21:52:23

EF架构~通过EF6的SQL命名拦截器来实现数据库读写分离的相关文章

EF架构~通过EF6的DbCommand拦截器来实现数据库读写分离~终结~配置的优化和事务里读写的统一

回到目录 本讲是通过DbCommand拦截器来实现读写分离的最后一讲,对之前几篇文章做了一个优化,无论是程序可读性还是实用性上都有一个提升,在配置信息这块,去除了字符串方式的拼接,取而代之的是section数组,这样在修改配置时更加清晰了:而实用性上,彻底改变了读和写不能共用一个仓储对象的缺点,并且在一个事务里可以读写并存,并为了数据的一致性,使事务里的curd操作指向主库,这一点很重要! 前几篇文章的目录 EF架构~通过EF6的DbCommand拦截器来实现数据库读写分离~再续~添加对各只读服

EF架构~通过EF6的DbCommand拦截器来实现数据库读写分离~再续~添加对各只读服务器的心跳检测

回到目录 上一讲中基本实现了对数据库的读写分离,而在选择只读数据库上只是随机选择,并没有去检测数据库服务器是否有效,如服务器挂了,SQL服务停了,端口被封了等等,而本讲主要对以上功能进行一个实现,并对配置文件也进行了一些优化,让它更好的支持多个数据库服务器,分别配置各个的账号和密码及数据库服务端口等等,接下来,就来看一下主要的代码吧. 一 配置文件 <!-- ef实现对sql读写分离的配置,sqlserver端采用发布与订阅实现 --> <add key="readDb&quo

EF架构~通过EF6的DbCommand拦截器来实现数据库读写分离~续~添加事务机制

回到目录 上一讲中简单介绍了一个EF环境下通过DbCommand拦截器来实现SQLSERVER的读写分离,只是一个最简单的实现,而如果出现事务情况,还是会有一些问题的,因为在拦截器中我们手动开启了Connection链接,而在一个WEB请求时,如果你的一个变量即用到了read库又用到了write库,就会导致到sqlserver端的spid(system process id,系统进程ID,sqlserver里可能是某个数据库进程序的ID)发生变化 ,而对于这种变化,原本是本地的事务就会自动提升为

大型网站架构演进(5)数据库读写分离

在使用缓存后,使大部分的数据读操作访问都可以不通过数据库就能完成,但是仍有一部分读操作(包括未命中缓存的,和缓存过期的)和全部的写操作需要访问数据库,当网站的访问量继续增加后,数据库会因为负载压力过高导致成为网站的性能瓶颈. 目前大部分的主流数据库都提供了主从热血功能,通过配置两台数据库的主从关系,可以将一台数据库服务器的数据同步到另一台服务器上,网站利用数据库的这一功能,可以实现数据库的读写分离,从而改善数据库的负载压力. 应用服务器在写数据的时候,访问主数据库,主数据库通过主从复制机制将数据

SQL Server 复制:事务发布(读写分离)

一.背景 在复制的运用场景中,事务发布是使用最为广泛的,我遇到这样一个场景:在YangJiaLeClub数据库中有表.存储过程.视图.用户定义函数,需要提供给其它程序读取放入缓存,程序需要比较及时的获取到这些数据,需要从权限和性能控制的角度出发,我采用了SQL Server的事务复制技术和timestamp,下面只讲述事务复制的搭建过程: 二.实现过程 (一) 环境信息   操作系统 IP 服务器名称 数据库版本 数据库名称 数据库帐号信息 发布服务器 Windows 10 企业版  192.1

SQL Server数据库读写分离提高并发性

在一些大型的网站或者应用中,单台的SQL Server 服务器可能难以支撑非常大的访问压力.很多人在这时候,第一个想到的就是一个解决性能问题的利器——负载均衡.遗憾的是,SQL Server 的所有版本,包括2012年3月发布的SQL Server 2012,也未提供该功能. 扩展单台SQL Server 服务器,解决性能瓶颈,有两种方法: 一.分布式数据库.扩展和分布数据库到多台服务器,由多台服务器分布存储不同的数据,通过将数据和访问压力分布到多台服务器来解决性能瓶颈.以一个大型电子商务网站数

ASP.NET Core搭建多层网站架构【8-使用AOP动态拦截器进行服务层日志记录】

2020/01/29, ASP.NET Core 3.1, VS2019 摘要:基于ASP.NET Core 3.1 WebApi搭建后端多层网站架构[7-编写角色业务的增删改查] 编写最简单的增删改业务,涉及到DI依赖注入的使用.AutoMapper的使用.工作单元与仓储的使用.雪花Id的生成 文章目录 此分支项目代码 本章节介绍了编写最简单的增删改查业务,涉及到DI依赖注入的使用.AutoMapper的使用.工作单元与仓储的使用 原文地址:https://www.cnblogs.com/ka

EF6.0新特性-DbCommandInterceptor实现非SQL端读写分离

前几天看了一个基于sqlserver的负载均衡与读写分离的软件Moebius,实现的方式还是不错的,这使得用sqlserver数据库的同学时有机会对数据库进行更有效的优化了 看着人有做的东西,自己也想用EF来实现一个读写分离,所以就有了本篇文章,仓储大叔读写分离的思路是: 1 用sqlserver自带的发布.订阅实现主,从数据库的结构,同步这事由sql帮我们完成 2 配置文件建立几个供只读的数据库连接串 3 建立SQL命令拦截器 4 修改大叔的DbContextRepository基数,添加拦截

JAVAEE——struts2_04:自定义拦截器、struts2标签、登陆功能和校验登陆拦截器的实现

一.自定义拦截器 1.架构 2.拦截器创建 //拦截器:第一种创建方式 //拦截器生命周期:随项目的启动而创建,随项目关闭而销毁 public class MyInterceptor implements Interceptor{} //创建方式2: 继承AbstractInterceptor -> struts2的体贴 //帮我们空实现了init 和 destory方法. 我们如果不需要实现这两个方法,就可以只实现intercept方法 public class MyInterceptor2