EntityFramework Core进行读写分离最佳实践方式,了解一下?

本来打算写ASP.NET Core MVC基础系列内容,博客评论有园友提出讲讲读写分离,这个问题提的好。


大多数情况下,对于园友在评论中提出的问题,如果是值得深究或者大多数同行比较关注的问题我都会私下去看看,然后进行对应解答。


若有叙述不当之处,还请海涵。我们稍微过一下事务,本文略长,请耐心阅读。


什么是事务呢?有关事务详解可参看我写的SQL Server基础系列,我们可归结为一句话:多个提交要么全部成功,要么全部失败即同生共死,没有临阵脱逃者。


那么问题来了,用了事务有什么作用或者说有什么优点呢?事务允许我们将相关操作组合打包,以确保应用程序数据的一致性。


那么使用事务又有何缺点呢?使用事务虽然确保了数据一致性等等,但是会影响性能,可能会造成死锁。


那么问题又来了,既然有其优缺点,那么我们是否可以手写逻辑实现数据一致性呢?当然可以,我们可以模拟事务回滚、提交的效果,但是这也无法百分百保证。


调用SaveChanges方法是否在事务中呢?


首先我们在控制台中进行如下数据添加,然后添加日志打印。

640?wx_fmt=png

640?wx_fmt=png

640?wx_fmt=png

我们通过打印日志得知在调用SaveChanges方法时则包含在事务中进行提交,所以请那些可在项目中用到多表添加担心出现问题就加上了如下开启事务,这很显然是多此一举。

640?wx_fmt=png

看到如上日志信息还不是更加确定是不是,我们再来看看在上下文中的context.Database.AutoTransactionsEnabled 方法,详细解释如下:

640?wx_fmt=png


通过AutoTransactionsEnabled方法解释得知:其默认值为True,也就意味着当调用SaveChanges方法将使用事务性提交。当然我们可以在上下文构造函数中设置是否全局禁用事务,如下:

640?wx_fmt=png


在EF Core中我们什么时候会用到事务呢?如果是单一上下文,单一数据库,那么事务跟我们没啥关系,压根不用管事务。如果是在单一数据库使用多个上下文(跨上下文)或者多个数据库,这个时候事务就闪亮登场了。


比如对于电商中的商品、购物车、订单管理、支付、物流,我们完全可以实例化五个不同的上下文,此时将涉及到跨上下文操作使用事务保持数据一致性,当然这是针对在同一关系数据库中。或者是实例化同一上下文多次来使用事务保持数据一致性。


可以参看官网的介绍《https://docs.microsoft.com/en-us/ef/core/saving/transactions》,没什么看头,都是针对同一数据库操作,无非还是我所说的跨上下文、使用上下文结合底层DbConnection来使用事务共享连接等等 


稍微大一点的看点则是在EF Core 2.1中引入了System.Transactions,可指定隔离级别以及使用ambient transactions(查资料作用是存在多个事务,事务之间存在连接,如此一来将显得整个作用域非常冗长,通过使用此事务则在特定范围内,所有连接都将包含在该事务中),在此就不占用篇幅介绍了。


和大家一样我们最关心的是分布式事务,也就是使用不同上下文针对多个数据库,但是遗憾的是直到EF Core 2.1还不支持分布式事务,因为.NET Core中相关APi也还不完善,继续等待吧。


随着流量的进入,数据库将承受不可抗拒的压力,单一数据库将不再适用,这都是随着项目的演变所带来架构的迭代改变,这个时候就涉及到分库,对于查询的数据单独作为一个数据库,作为数据的更改也单独用一个数据库,再结合那些什么负载均衡等等,数据库压力也就减弱了许多。


只作查询的数据库我们称之为从数据库,对于数据库更改的数据库称之为主数据库,主-从数据库(Master-Slave)数据的同步方式也有很多。


虽然我也没接触过,我们就利用SQL Server中的复制进行发布-订阅来模拟演示还是可以的。我们来看看.NET Core Web应用程序如何实现读写分离。


额外加一句,项目中我也未用到,都是我私下的研究,方案行不行,合不合理可以一起探讨。我们创建了两个Demo数据库,如下:

640?wx_fmt=png


我们将Demo1作为主数据库,Demo2作为从数据库,接下来用一张动态图演示创建复制发布-订阅(每隔10秒发布一次)。


我们给出Demo1上下文,Demo2和其一样,按照正常做法接下来我们应该在.NET Core Web应用程序中注入Demo1和Demo2上下文,如下:

640?wx_fmt=png

640?wx_fmt=png

640?wx_fmt=png


然后我们创建Demo控制器,通过Demo1上下文添加数据,Demo2上下文读取数据,如下:

640?wx_fmt=png

640?wx_fmt=png

640?wx_fmt=png

640?wx_fmt=png

640?wx_fmt=gif


我们看到通过Demo1上下文添加数据后重定向到Demo2上下文查询到的列表页面,到了10秒自动同步到Demo2数据库,通过刷新可以看到数据显示。


虽然结果如我们所期望,但是实现的路径却令我们不是那么如意,因为所用实体都是一样的,只是说所连接数据库不一样而已,但是我们需要创建两个不同的上下文实例,很显然这不是最佳实践方式。


那么我们如何做才是最佳实践方式呢?接下来我们再来创建一个Demo3数据库,表结构和Demo1、Demo2一致,如下:

640?wx_fmt=png


接下来我们在.NET Core Web应用程序Demo1、Demo2上下文所在的类库中创建如下扩展方法(方便有同行需要学习,给出Demo项目基本结构)。

640?wx_fmt=png

640?wx_fmt=png

我们暂且不去看为何这样设置,我们只是添加上下文扩展方法,更改连接为Demo3的数据库,然后接下来我们获取博客列表时,调用上述扩展方法,请问:是否可以获取到Demo3的数据或者说是否会抛出异常呢?我们依然通过动态图来进行演示,如下:

640?wx_fmt=gif


一直以来我们认为利用 context.Database.GetDbConnection() 方法可以回到ADO.NET进行查询。


但是我们通过实际证明,我们可以设置其他数据库连接从而达到读写分离最佳实践方式,免去再实例化一个上下文。


所以对于上述我们配置的Demo1和Demo2上下文,我们大可只需要Demo1上下文即主数据库,对于从数据库进行查询,我们只需在Demo1上下文的基础上更该连接字符串即可,如下:

640?wx_fmt=png


接下来问题来了,那么为何更改Demo1上下文连接字符串就能转移到其他数据库查询呢?就是为了解决读写分离免去实例化上下文即Demo2的情况,但是内部是如何实现的呢?


因为EF Core内部添加了方法实现IRelationalConnection接口,使得我们可以在已存在的上下文实例上重新设置连接字符串即更换数据库,但是其前提是必须保证当前上下文连接已关闭。


也就是说比如我们在同一个事务中利用当前上下文进行更改操作,然后更改连接字符串进行更改操作,最后提交事务,因为在此事务内,当前上下文连接还未关闭,所以再更改连接字符串后进行数据库更改操作,将必定会抛出异常。


花了两天时间研究研究,本文比较详细讲解了对于读写分离后,如何进行数据查询和更改操作最佳实践方式,不知道算不算最好的解决方案,若您有更好的方案,欢迎一起探讨或者说还有其他理解和疑问,也欢迎在留言中提出,下节我们讲讲ASP.NET Core MVC基础系列。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/320956.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

P3980 NOI2008志愿者招募

志愿者招募 题目链接 https://www.luogu.org/problemnew/show/P3980 题解 这道题很神奇,这种建图方法很有启发性. 我们平时做的题都点都是是一对一的,而这道题的点的对应关系是一对多(即一个志愿者对应一段连续的区间,也就是多个时间点)的,直接按照传统的网络流建图方法来…

小X的加法难题

小X的加法难题 题目大意&#xff1a; 一个AB的式子&#xff0c;但之间有一些没用的空格&#xff0c;要你求出结果 原题&#xff1a; 解题思路&#xff1a; 字符输入&#xff0c;有数字就存起来&#xff0c;用加号和换行符来分开 代码&#xff1a; #include<cstdio>…

P3857-[TJOI2008]彩灯【线性基】

正题 题目链接:https://www.luogu.com.cn/problem/P3857 题目大意 nnn个彩灯&#xff0c;mmm个开关能使得某些彩灯取反&#xff0c;求有多少种彩灯样式。 解题思路 其实就是mmm个数种若干个数异或起来有多少不同的数。 又是一道考线性基性质的题目&#xff0c;因为线性基中任…

【桶排】小 X 的密码破译

小 X 的密码破译 题目大意&#xff1a; 有一堆式子&#xff0c;去重再排序后&#xff0c;按规则求出结果 原题&#xff1a; 解题思路&#xff1a; 把每一个求出来的数丢到桶里&#xff0c;然后跑一遍就可以了 代码&#xff1a; #include<cstdio> using namespace s…

Uva12325 Zombie's Treasure Chest [二分区间+模拟退火]

Zombie’s Treasure Chest 题目链接 https://cn.vjudge.net/problem/UVA-12325 题意 两种物品无穷多个,第一种物品重量s1s_1s1​,价值v1v_1v1​,第二种物品重量s2s_2s2​,价值v2v_2v2​,背包重nnn,求能装的最大价值之和. 数据全都是2e92e92e9.也就是两种物品的完全背包. 题…

Identity Server 4 预备知识 -- OpenID Connect 简介

我之前的文章简单的介绍了OAuth 2.0 (在这里: 要用Identity Server 4 -- OAuth 2.0 超级简介, 还不是很全.这篇文章我要介绍一下 OpenID Connect.OAuth 2.0 不是身份认证协议OAuth 2.0 不是身份认证(Authentication)协议. 为什么有人会认为OAuth 2.0具有身份认证的功能? 这是因…

P4301-[CQOI2013]新Nim游戏【线性基】

正题 题目链接:https://www.luogu.com.cn/problem/P4301 题目大意 nnn个石头&#xff0c;先手先取走若干堆&#xff08;不能全取&#xff0c;可以不取&#xff09;&#xff0c;后手取走若干堆&#xff08;不能全取&#xff0c;可以不取&#xff09;。然后进行NimNimNim游戏&am…

P2414 NOI2011阿狸的打字机 [AC自动机,dfs序]

阿狸的打字机 题解 题目中给出的字符串就是构建TrieTrieTrie树的顺序.我们将字符串依次读入,每读入一个小写字符就相当于在TrieTrieTrie树当前节点下插入一个小写字符,读入BBB时,就在TrieTrieTrie树中向父节点移动一步.读入PPP的时候,就做一个标记. 然后对这颗TrieTrieTrie树…

Ocelot.JwtAuthorize:一个基于网关的Jwt验证包

Ocelot作为基于.net core的API网关&#xff0c;有一个功能是统一验证&#xff0c;它的作用是把没有访问权限的请求挡在API网关外面&#xff0c;而不是到达API网关事端的API时才去验证&#xff1b;之前我有一篇博文Ocelot统一权限验证&#xff0c;作过说明&#xff0c;这篇博文说…

【并查集】小 X 的液体混合

小 X 的液体混合 题目大意&#xff1a; 在一个玻璃瓶里&#xff0c;放入一些液体&#xff0c;某一对液体放在一起会有反应&#xff0c;当某个液体有反应时危险度就会乘2&#xff08;初值为1&#xff09;&#xff0c;问危险度最大是多少 原题&#xff1a; 解题思路&#xff1…

P4151-[WC2011]最大XOR和路径【线性基】

正题 题目链接:https://www.luogu.com.cn/problem/P4151 题目大意 给一个无向图&#xff0c;求一条1∼n1\sim n1∼n的路径使得异或和最大。 解题思路 很强的思路啊&#xff08;好像去年YPXYPXYPX大爷就讲了反正我也没听懂&#xff09; 我们可以将路径拆分成三部分&#xff…

Swagger如何访问Ocelot中带权限验证的API

先亮源代码&#xff1a;https://github.com/axzxs2001/Asp.NetCoreExperiment/tree/master/Asp.NetCoreExperiment/SwaggerDemo这篇博文不是对asp.net core中使用Swagger作介绍&#xff0c;因为社区博客作了详细说明。今天主要说一下Swagger在Ocelot网关权限验证模式下的访问&a…

初一模拟赛总结(2019.4.13)

成绩&#xff1a; rank是有算其他dalaodalaodalao的 注&#xff1a; 这次好像是因为OJ有问题&#xff0c;导致一些AC代码变&#xff08;bei&#xff09;W&#xff08;zhi&#xff09;A&#xff08;cai&#xff09;了 rankrankranknamenamenamescorescorescoreT1T1T1T2T2T2T3T3…

etcd-workbench一款免费好用的ETCD客户端,支持SSHTunnel、版本对比等功能

介绍 今天推荐一款完全免费的ETCD客户端&#xff0c;可以私有化部署: etcd-workbench 开源地址&#xff1a;https://github.com/tzfun/etcd-workbench Gitee地址&#xff1a;https://gitee.com/tzfun/etcd-workbench 下载 本地运行 从 官方Release 下载最新版的 jar 包&am…

深度学习中反向传播算法简单推导笔记

反向传播算法简单推导笔记 1.全连接神经网络 该结构的前向传播可以写成: z(1)W(1)xb(1)z^{(1)} W^{(1)}xb^{(1)}z(1)W(1)xb(1) a(1)σ(z(1))a^{(1)} \sigma(z^{(1)})a(1)σ(z(1)) z(2)W(2)a(1)b(2)z^{(2)}W^{(2)}a^{(1)}b^{(2)}z(2)W(2)a(1)b(2) a(2)σ(z(2))a^{(2)} \sigm…

EntityFramework Core进行读写分离最佳实践方式,了解一下(二)?

写过上一篇关于EF Core中读写分离最佳实践方式后&#xff0c;虽然在一定程度上改善了问题&#xff0c;但是在评论中有的指出更换到从数据库。那么接下来要进行插入此时又要切换到主数据库&#xff0c;同时有的指出是否可以进行底层无感知操作&#xff0c;这确实是个问题&#x…

【图论】【Kosaraju】刻录光盘(ssl 2344)

刻录光盘 ssl 2344 题目大意&#xff1a; 求连通块 原题&#xff1a; 题目描述 在JSOI2005夏令营快要结束的时候&#xff0c;很多营员提出来要把整个夏令营期间的资料刻录成一张光盘给大家&#xff0c;以便大家回去后继续学习。组委会觉得这个主意不错&#xff01;可是组…

P4158-[SCOI2009]粉刷匠【dp,背包】

正题 https://www.luogu.com.cn/problem/P4158 题目大意 nnn个墙长度为mmm&#xff0c;每次可以粉刷一堵墙的连续一段区间&#xff0c;粉刷过的不能再粉刷。给出每个位置应该粉刷的颜色&#xff0c;然后求TTT次可以粉刷正确多少个位置。 解题思路 首先我们对于第iii堵墙处理出…

一文搞清到底什么是 .NET?

现在各种 .NET 满天飞&#xff0c;别说新手了&#xff0c;连我这样的老手都差点被绕进去。到底什么是 .NET 呢&#xff1f;通俗易懂&#xff0c;什么是.NET?什么是.NET Framework&#xff1f;什么是.NET Core? 这篇文章好长呀&#xff0c;不知道你看完了没有&#xff0c;其实…

P4552-[Poetize6]IncDec Sequence【差分】

正题 题目链接:https://www.luogu.com.cn/problem/P4552 题目大意 给出nnn个数&#xff0c;每次可以选择一个区间加一或减一&#xff0c;求最少操作使得所有数相等&#xff0c;并且求可能的最终序列个数。 解题思路 在差分数组上操作&#xff0c;那么操作变为将差分数组上一…