EFCore废弃了TransactionScope取而代之的Context.Database.BeginTransaction

TransactionScope是.net平台基于的分布式事务组件,它默认为本地事务,同时当系统有需要时可以自动提升为分布式事务,而对系统的前提是要开启MSDTC服务,必要时需要在数据库服务器与应用服务器之间添加hosts的映射,这些在之前已经写过很多文章了,在这里不再说了。


在efcore平台时,你使用TransactionScope将会出现异常,微软会提示你去查看相关资料,这回资料挺准!https://docs.microsoft.com/en-us/ef/core/saving/transactions

本文章主要说了几点内容

  1. 默认的事务-savechanges依旧是一个事务

  2. 单个上下文实现事务

  3. 不同上下文之间实现事务

一 savechanges依旧是一个事务

和之前的ef一样,在进行saveChanges()操作时,本身就是一个事务块,而大叔仓储习惯把每个操作curd都有自己的saveChanges里,而把数据上下文的savechanges对外隐藏,所以如果你要对两个仓储进行insert操作时,你需要添加一个外层的事务来保证数据一致性,这时微软给出了解决方案。

二 单个上下文实现事务

对于一个数据上下文来说,如果你是多个savechanges,那么可以使用context.Database.BeginTransaction()来实现事务。

using (var context = new BloggingContext())

        {

            using (var transaction = context.Database.BeginTransaction())

            {

                try

                {

                    context.Blogs.Add(new Blog { Url = "http://blogs.msdn.com/dotnet" });

                    context.SaveChanges();


                    context.Blogs.Add(new Blog { Url = "http://blogs.msdn.com/visualstudio" });

                    context.SaveChanges();


                    var blogs = context.Blogs

                        .OrderBy(b => b.Url)

                        .ToList();


                    // Commit transaction if all commands succeed, transaction will auto-rollback

                    // when disposed if either commands fails

                    transaction.Commit();

                }

                catch (Exception)

                {

                    // TODO: Handle failure

                }

            }

        }

三 不同上下文之间实现事务

对于前面的TransactionScope来说,如果是不同的数据上下文来说,我们是无法实现事务操作的,有些同学可以能说它应该被提升为分布式的,但对于EF来说,它是不同实现的,但进行efcore时代之后,这个问题得到了解决!

Cross- only available when a relational database provider because it requires the use of DbTransaction and DbConnection, 
which are specific to relational databases.

上面说明,可以实现一个跨数据上下文的事务,只关系型数据库支持!这个功能大叔认为非常必要,但看它下面给出的实例是针对一个数据上下文的,并不多个上下文的交

叉事务,即并不是两个数据库之间的事务

using (var context1 = new BloggingContext(options))

        {

            using (var transaction = context1.Database.BeginTransaction())

            {

                try

                {

                    context1.Blogs.Add(new Blog { Url = "http://blogs.msdn.com/dotnet" });

                    context1.SaveChanges();


                    using (var context2 = new BloggingContext(options))

                    {

                        context2.Database.UseTransaction(transaction.GetDbTransaction());


                        var blogs = context2.Blogs

                            .OrderBy(b => b.Url)

                            .ToList();

                    }


                    // Commit transaction if all commands succeed, transaction will auto-rollback

                    // when disposed if either commands fails

                    transaction.Commit();

                }

                catch (Exception)

                {

                    // TODO: Handle failure

                }

            }

        }

而如果真正使用多个上下文进行事务的话,同样会出现问题:

var options = new DbContextOptionsBuilder<DemoContext>()

                          .UseMySql("Server=localhost;DataBase=test2;UID=root;Password=root;charset=utf8;port=3306;SslMode=None")

                          .Options;

            using (var context = new DemoContext(options))

            {

                using (var transaction = context.Database.BeginTransaction())

                {

                    var user = new UserInfo

                    {

                        AddTime = DateTime.Now,

                        Email = "test@sina.com",

                        UserName = "test"

                    };

                    context.UserInfo.Add(user);

                    context.SaveChanges();

                    using (var context2 = new TaxContext())

                    {

                        context2.Database.UseTransaction(transaction.GetDbTransaction());

                        context2.UserInfo.Add(new UserInfo { AddTime = DateTime.Now, Email = "tax_test", UserName = "tax" });

                        context2.SaveChanges();

                    }

                    transaction.Commit();

                }

            }

出现下面异常:告诉你,你的数据库连接不是当前的连接

System.InvalidOperationException:“The specified transaction  not associated with the current connection.Only transactions associated with the current connection may be used.”

不知道什么时候EF可以解决多数据库事务的问题,当前你可以使用最终一致性的分布式事务来做这事,不过我们还是一起期待中微软为我们提出更简单的解决方案,一个事务

是否为分布式的,应该看数据库所在服务器是否相同,而不是数据库连接串是否一致!

感谢微软这么完整的解释!

原文地址:http://www.cnblogs.com/lori/p/7659923.html


.NET社区新闻,深度好文,微信中搜索dotNET跨平台或扫描二维码关注

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

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

相关文章

从 Spring Cloud 看一个微服务框架的「五脏六腑」

转载自 从 Spring Cloud 看一个微服务框架的「五脏六腑」 Spring Cloud 是一个基于 Spring Boot 实现的微服务框架&#xff0c;它包含了实现微服务架构所需的各种组件。 注&#xff1a;Spring Boot 简单理解就是简化 Spring 项目的搭建、配置、组合的框架。因为与构建微服务本…

eclipse导入github项目

首先登录github&#xff0c;找到项目&#xff0c;复制项目地址 复制地址在上面 即可导入成功 然后现在就可以玩游戏了 空手套白狼&#xff0c;github真的是白嫖&#xff0c;程序员必备之品。

nssl1256-C(盟主的忧虑)【并查集】

正题 题目大意 n个点的一棵树&#xff0c;增加了m条密道。对于树上每条边(A,B)(A,B)(A,B)被破坏后&#xff0c;要求A∼BA\sim BA∼B经过密道最短。 解题思路 引理:对于每个道路被破坏&#xff0c;最多只会经过一条边。 证明:对于每个答案&#xff0c;被破坏后&#xff0c;所在…

From Agile To DevOps - 微软开发部门 DevOps 经验谈

在 2013 年 11 月 13 日&#xff0c;我们正式发行了 Visual Studio 2013&#xff0c;以及全新的 Visual Studio Online 服务。但在服务发表之后&#xff0c;Visual Studio Online 却发⽣了异常&#xff0c;造成七个小时服务中断&#xff0c;这是因为在服务上线时&#xff0c;我…

RESTful API 最佳实践

转载自 RESTful API 最佳实践 RESTful 是目前最流行的 API 设计规范&#xff0c;用于 Web 数据接口的设计。 它的大原则容易把握&#xff0c;但是细节不容易做对。本文总结 RESTful 的设计细节&#xff0c;介绍如何设计出易于理解和使用的 API。 一、URL 设计 1.1 动词 宾…

selenium以及chromdrive安装

selenium的安装比较简单&#xff0c;直接pip install selenium就可以了 看有些网上写的chromedrive安装好麻烦啊&#xff0c;我win10自己试了下&#xff0c;感觉并不需要配置那么多环境变量。 直接性 http://npm.taobao.org/mirrors/chromedriver/ 找到相应的chrome版本即可 至…

将两个递增的有序链表合并为一个递增的有序链表。要求结果链表仍使用原来两个链表的存储空间,不另外占用其他的空间。表中不允许又重复的数据

#include<iostream> using namespace std;typedef struct lnode {//定义结点类型int data;struct lnode *next;//递归定义 } lnode,*LinkList;void CreateList(LinkList &L,int n) {//创建新链表Lnew lnode;//生成一个头结点L->nextNULL;//结点L的next置空for(int…

ssl提高组周二备考赛【2018.10.30】

前言 依旧想去德育基地… 成绩 RankRankRankPersonPersonPersonScoreScoreScoreAAABBBCCC1112017xxy2017xxy2017xxy2102102104040401001001007070702222017myself2017myself2017myself1901901902020201001001007070703332017lxf2017lxf2017lxf1801801800009090909090904442017…

通过C#/.NET API使用CNTK

CNTK v2.2.0提供C#API来建立、训练和评估CNTK模型。 本节概要介绍了CNTK C#API。 在CNTK github respository中可以找到C#训练示例。 使用C&#xff03;/ .NET管理API构建深层神经网络 CNTK C#API 通过CNTKLib命名空间提供基本操作。 CNTK操作需要一个或两个具有必要参数的输入…

Kafka Controller Redesign 方案

转载自 Kafka Controller Redesign 方案 Kafka Controller 是 Kafka 的核心组件&#xff0c;在前面的文章中&#xff0c;已经详细讲述过 Controller 部分的内容。在过去的几年根据大家在生产环境中应用的反馈&#xff0c;Controller 也积累了一些比较大的问题&#xff0c;而针…

做个人网站的原因

昨天b站上看视频&#xff0c;浏览评论时&#xff0c;看到一个网址 https://xiaoyou66.com/ 博主写了大概一百篇的文章&#xff0c;我进来的时候真的是被这js特效给惊到了&#xff0c;个人网站也能变得这么二次元嘛&#xff0c;讲实话&#xff0c;光是看这酷炫的页面都比较有欲望…

nssl1257-A【数论】

正题 题目大意 对于n个数组成的序列&#xff0c;求排好序需要最少交换次数的期望次数。 解题思路 我们可以先求出需要次数总和在乘上n!n!n!的逆元 先打一个表&#xff0c;不难发现 f(n)f(n−1)∗n(n−1)(n−1)!f(n)f(n-1)*n(n-1)(n-1)!f(n)f(n−1)∗n(n−1)(n−1)! 然后我们在…

一文理解Netty模型架构

转载自 一文理解Netty模型架构 本文基于Netty4.1展开介绍相关理论模型&#xff0c;使用场景&#xff0c;基本组件、整体架构&#xff0c;知其然且知其所以然&#xff0c;希望给读者提供学习实践参考。 1 Netty简介 Netty是 一个异步事件驱动的网络应用程序框架&#xff0c;用…

尝试涉猎更多领域

昨天b站上看视频&#xff0c;浏览评论时&#xff0c;看到一个网址 https://xiaoyou66.com/ 博主写了大概一百篇的文章&#xff0c;我进来的时候真的是被这js特效给惊到了&#xff0c;个人网站也能变得这么二次元嘛&#xff0c;讲实话&#xff0c;光是看这酷炫的页面都比较有欲望…

nssl1258-naive的瓶子【贪心】

正题 题目大意 有n个瓶子&#xff0c;将一个瓶子变成相邻一个瓶子的颜色价值为它们颜色值的乘积&#xff0c;求将所有瓶子变成同一个颜色的最低价值。 解题思路 枚举最后的剩下的颜色&#xff0c;然后对于每个瓶子只有两种可能 1.直接变成那个颜色 2.变成别的颜色在变成那个颜…

聊聊分布式事务,再说说解决方案

前言 最近很久没有写博客了&#xff0c;一方面是因为公司事情最近比较忙&#xff0c;另外一方面是因为在进行 CAP 的下一阶段的开发工作&#xff0c;不过目前已经告一段落了。 接下来还是开始我们今天的话题&#xff0c;说说分布式事务&#xff0c;或者说是我眼中的分布式事务&…

已知两个链表A和B分别表示两个集合,其元素递增排列。请设计算法求出两个集合A和集合B的差集(近由在A中出现而不再B中出现的元素所构成的集合),并以同样的形式存储,同时返回该集合的元素个数。

#include <iostream> using namespace std; //第四题 typedef struct Lnode {int data;struct Lnode *next;} lnode, *linklist; void creatlist_h(linklist &L, int n) {lnode *p;Lnew lnode;L->nextNULL;for(int i0; i<n; i){pnew lnode;cin>>p->da…

Redis+Tomcat+Nginx集群实现Session共享,Tomcat Session共享

转载自 RedisTomcatNginx集群实现Session共享&#xff0c;Tomcat Session共享 一、Session共享使用tomcat-cluster-redis-session-manager插件实现 插件地址见&#xff1a; https://github.com/ran-jit/tomcat-cluster-redis-session-manager 该插件支持Tomcat7、Tomcat8、To…

个人博客搭建

先下载node.js 用npm或cnpm安装hexo cnpm install hexo 再创建一个文件夹&#xff0c;在文件夹目录下打开cmd 输入 hexo init 输入 hexo s 这就在本地算是完成了一个博客的创建 新建博客hexo n ‘Hello world’ hexo clean hexo s 就可以再次启动&#xff0c;这样 记得先 cn…

C#使用Xamarin开发可移植移动应用进阶篇(10.综合演练,来一份增删改查CRUD)

说点什么.. 呃 也有半个月没更新了. 本来这篇的Demo早就写完了,文章也构思好了.迟迟没发布..是因为实在太忙.. 项目要上线..各种 你们懂的.. 正赶上自己十一人生大事..结婚..所以..忙的那叫一个脚不沾地啊. 今天的学习内容? 使用我们前面所学的技术,写一个增删改查. 效果如下…