基于 EntityFramework 的数据库主从读写分离架构(2)- 改进配置和添加事务支持...
1 public class DbMasterSlaveCommandInterceptor : DbCommandInterceptor 2 { 3 private Lazy<string> masterConnectionString = new Lazy<string>(() => ConfigurationManager.AppSettings["masterConnectionString"]); 4 private Lazy<string> slaveConnectionString = new Lazy<string>(() => ConfigurationManager.AppSettings["slaveConnectionString"]); 5 6 public string MasterConnectionString 7 { 8 get { return this.masterConnectionString.Value; } 9 } 10 11 public string SlaveConnectionString 12 { 13 get { return this.slaveConnectionString.Value; } 14 } 15 16 17 public override void ReaderExecuting(DbCommand command, DbCommandInterceptionContext<DbDataReader> interceptionContext) 18 { 19 this.UpdateConnectionStringIfNeed(interceptionContext, this.SlaveConnectionString); 20 } 21 22 public override void ScalarExecuting(DbCommand command, DbCommandInterceptionContext<object> interceptionContext) 23 { 24 this.UpdateConnectionStringIfNeed(interceptionContext, this.SlaveConnectionString); 25 } 26 27 public override void NonQueryExecuting(DbCommand command, DbCommandInterceptionContext<int> interceptionContext) 28 { 29 this.UpdateConnectionStringIfNeed(interceptionContext, this.MasterConnectionString); 30 } 31 32 33 private void UpdateConnectionStringIfNeed(DbInterceptionContext interceptionContext, string connectionString) 34 { 35 foreach (var context in interceptionContext.DbContexts) 36 { 37 this.UpdateConnectionStringIfNeed(context.Database.Connection, connectionString); 38 } 39 } 40 41 /// <summary> 42 /// 此处改进了对连接字符串的修改判断机制,确认只在 <paramref name="conn"/> 所使用的连接字符串不等效于 <paramref name="connectionString"/> 的情况下才需要修改。 43 /// </summary> 44 /// <param name="conn"></param> 45 /// <param name="connectionString"></param> 46 private void UpdateConnectionStringIfNeed(DbConnection conn, string connectionString) 47 { 48 if (this.ConnectionStringCompare(conn, connectionString)) 49 { 50 ConnectionState state = conn.State; 51 if (state == ConnectionState.Open) 52 conn.Close(); 53 54 conn.ConnectionString = connectionString; 55 56 if (state == ConnectionState.Open) 57 conn.Open(); 58 } 59 } 60 61 private bool ConnectionStringCompare(DbConnection conn, string connectionString) 62 { 63 DbProviderFactory factory = DbProviderFactories.GetFactory(conn); 64 65 DbConnectionStringBuilder a = factory.CreateConnectionStringBuilder(); 66 a.ConnectionString = conn.ConnectionString; 67 68 DbConnectionStringBuilder b = factory.CreateConnectionStringBuilder(); 69 b.ConnectionString = connectionString; 70 71 return a.EquivalentTo(b); 72 } 73 }
再者,我们来聊聊数据库操作中的事务处理。
1 public class DbMasterSlaveCommandInterceptor : DbCommandInterceptor 2 { 3 private Lazy<string> masterConnectionString = new Lazy<string>(() => ConfigurationManager.AppSettings["masterConnectionString"]); 4 private Lazy<string> slaveConnectionString = new Lazy<string>(() => ConfigurationManager.AppSettings["slaveConnectionString"]); 5 6 public string MasterConnectionString 7 { 8 get { return this.masterConnectionString.Value; } 9 } 10 11 public string SlaveConnectionString 12 { 13 get { return this.slaveConnectionString.Value; } 14 } 15 16 17 public override void ReaderExecuting(DbCommand command, DbCommandInterceptionContext<DbDataReader> interceptionContext) 18 { 19 this.UpdateToSlave(interceptionContext); 20 } 21 22 public override void ScalarExecuting(DbCommand command, DbCommandInterceptionContext<object> interceptionContext) 23 { 24 this.UpdateToSlave(interceptionContext); 25 } 26 27 public override void NonQueryExecuting(DbCommand command, DbCommandInterceptionContext<int> interceptionContext) 28 { 29 this.UpdateToMaster(interceptionContext); 30 } 31 32 33 private void UpdateToMaster(DbInterceptionContext interceptionContext) 34 { 35 foreach (var context in interceptionContext.DbContexts) 36 { 37 this.UpdateConnectionStringIfNeed(context.Database.Connection, this.MasterConnectionString); 38 } 39 } 40 41 private void UpdateToSlave(DbInterceptionContext interceptionContext) 42 { 43 // 判断当前会话是否处于分布式事务中 44 bool isDistributedTran = Transaction.Current != null && Transaction.Current.TransactionInformation.Status != TransactionStatus.Committed; 45 foreach (var context in interceptionContext.DbContexts) 46 { 47 // 判断该 context 是否处于普通数据库事务中 48 bool isDbTran = context.Database.CurrentTransaction != null; 49 50 // 如果处于分布式事务或普通事务中,则“禁用”读写分离,处于事务中的所有读写操作都指向 Master 51 string connectionString = isDistributedTran || isDbTran ? this.MasterConnectionString : this.SlaveConnectionString; 52 53 this.UpdateConnectionStringIfNeed(context.Database.Connection, connectionString); 54 } 55 } 56 57 58 /// <summary> 59 /// 此处改进了对连接字符串的修改判断机制,确认只在 <paramref name="conn"/> 所使用的连接字符串不等效于 <paramref name="connectionString"/> 的情况下才需要修改。 60 /// <para>同时,在必要的情况下才会连接进行 Open 和 Close 操作以及修改 ConnectionString 处理,减少了性能的消耗。</para> 61 /// </summary> 62 /// <param name="conn"></param> 63 /// <param name="connectionString"></param> 64 private void UpdateConnectionStringIfNeed(DbConnection conn, string connectionString) 65 { 66 if (this.ConnectionStringCompare(conn, connectionString)) 67 { 68 this.UpdateConnectionString(conn, connectionString); 69 } 70 } 71 72 private void UpdateConnectionString(DbConnection conn, string connectionString) 73 { 74 ConnectionState state = conn.State; 75 if (state == ConnectionState.Open) 76 conn.Close(); 77 78 conn.ConnectionString = connectionString; 79 80 if (state == ConnectionState.Open) 81 conn.Open(); 82 } 83 84 private bool ConnectionStringCompare(DbConnection conn, string connectionString) 85 { 86 DbProviderFactory factory = DbProviderFactories.GetFactory(conn); 87 88 DbConnectionStringBuilder a = factory.CreateConnectionStringBuilder(); 89 a.ConnectionString = conn.ConnectionString; 90 91 DbConnectionStringBuilder b = factory.CreateConnectionStringBuilder(); 92 b.ConnectionString = connectionString; 93 94 return a.EquivalentTo(b); 95 } 96 }
转载于:https://www.cnblogs.com/cjw0511/p/4398502.html
基于 EntityFramework 的数据库主从读写分离架构(2)- 改进配置和添加事务支持...相关推荐
- 基于 EntityFramework 的数据库主从读写分离架构(1) - 原理概述和基本功能实现...
回到目录,完整代码请查看(https://github.com/cjw0511/NDF.Infrastructure)中的目录: src\ NDF.Data.EntityFramework\Maste ...
- ef mysql 读写分离_基于 EntityFramework 的数据库主从读写分离服务插件
基于 EntityFramework 的数据库主从读写分离服务插件 1. 版本信息和源码 1.1版本信息 v1.01 beta(2015-04-07),基于 EF 6.1 开发,支持 EF 6.1 之 ...
- django给mysql配主从_django中的mysql主从读写分离:一、配置mysql主从分离
一.配置mysql主从同步的步骤: (1) 在主服务器上,必须开启二进制日志机制和配置一个独立的ID (2) 在每一个从服务器上,配置一个唯一的ID,创建一个用来专门复制主服务器数据的账号 (3) 在 ...
- Django项目配置mysql主从数据库实现读写分离
1.在配置文件中添加slave数据库的配置 DATABASES = { 'default': { 'ENGINE': 'django.db.backends.mysql', ...
- 数据库之架构:主备+分库?主从+读写分离?
数据库之架构:主备+分库?主从+读写分离? 原文:数据库之架构:主备+分库?主从+读写分离? 一.数据库架构原则 高可用 高性能 一致性 扩展性 二.常见的架构方案 方案一:主备架构,只有主库提供读写 ...
- 数据库读写分离架构详解
RD:数据量太大,数据库扛不住了,帮忙申请一个从库,读写分离. DBA:数据量多少? RD:5000w左右. DBA:读写吞吐量呢? RD:读QPS约200,写QPS约30左右. 额,数据库读写分离虽 ...
- mysql查询并设置高亮_Thinkphp3.2.3设置MySql主从读写分离后,简单调用主数据库查询
图/文:迷神 Thinkphp是一款不错的国产框架,使用范围广,应用也比较多.随着网站访问增大往往需要使用mysql主从同步功能,本身Thinkphp自带了主从读写分离的功能了. 但是我们经常有一个场 ...
- MySQL数据库:读写分离
一.读写分离的原理: 1.实现原理: 读写分离解决的是,数据库的写操作,影响了查询的效率,适用于读远大于写的场景.读写分离的实现基础是主从复制,主数据库利用主从复制将自身数据的改变同步到从数据库集群中 ...
- 基于mycat的mysql_基于Mycat中间件的MySQL读写分离
基于Mycat中间件的MySQL读写分离 简述 mycat是国内开源的数据库中间件,可以实现mysql读写分离和主备热切换,容灾,数据分片等功能. 详情:http://www.mycat.io/ 架构 ...
最新文章
- 【bzoj2423】最长公共子序列[HAOI2010](dp)
- Spring---------ThreadLocal(线程变量副本)
- php多文件上传存储到表,PHP 实现一种多文件上传的方法
- BugkuCTF-MISC题粗心的佳佳
- 音频放大电路_低音升压功率放大器电子电路的完整设计
- Python 基础 —— from __future__ import
- Vue基本指令(详细,好理解,示例代码)
- android接支付宝授权和支付功能
- 模拟生成随机四位GB2312的汉字验证码(python3.X)
- 人人都喜欢用的十大python标准库
- windows 7 RC(7106.0.090408)下载另附windows7驱动收集整合(5月31日更新)
- C++“准”标准库Boost学习指南(3):Boost.Utility
- Unity+Kinect 开发脚本介绍
- 【老九学堂】【初识C语言】编译过程
- 时统ptp_IEEE1588对时系统,PTP校时模块,PTP时钟服务器
- 计算机查看配置的快捷键,剪映电脑版快捷键在哪里设置? 剪映查看快捷键的技巧...
- html 仿word页面,HTML+CSS入门 HTML页面仿WORD样式详解
- 全球名校AI课程库(1)| 深度学习专项课程『Deep Learning Specialization』
- 微信内置浏览器无法打开APP下载链接的解决方案
- 研发管理--测试绩效管理