原标题:TransactionScope事务处理方法介绍及.NET Core中的注意事项

作者:依乐祝

原文链接:https://www.cnblogs.com/yilezhu/p/10170712.html

今天在写CzarCms的UnitOfWork的使用使用到了这个TransactionScope事务,因此对它进行了相关资料的查阅并记录如下,希望对大伙在.NET Core中使用有所帮助。

写在前面

您是否曾尝试使用C#代码来实现事务?通常,我们在SQL中一次执行多个Insert / Update语句的话可能就会使用到事务。事务遵循ACID(原子性,一致性,隔离性,持久性)规则,这样所有的语句要么全部执行成功要么全部被取消并执行回滚操作。 而我们今天要讲的TransactionScope则可以允许我们在应用程序级别实现这个过程。在某些情况下,您可能需要在同一个数据库甚至多个数据库(分布式事务)中执行不同的操作,或者由于某些其他约束,它无法在数据库级别来完成,或者应用程序的开发人员对数据库的接触较少,那么这时候TransactionScope将会让你游刃有余。

什么是TransactionScope呢?

TransactionScope作为System.Transactions的一部分被引入到.NET 2.0。同时SqlClient for .NET Core 从 2.1 及以上版本开始提供对System.Transactions的支持 。 它是一个类,它提供了一种简单的方法,可以将一组操作作为事务的一部分来进行处理,而不必担心场景背后的复杂性。如果某个操作在执行的过程中失败的话,则整个事务将失败并执行回滚操作,从而撤消已完成的所有操作。所有这些都将由框架处理,从而确保数据的一致性。

如何使用TransactionScope呢?

要使用它,您需要添加System.Transactions的引用,如果你使用的是.net core的话。这个引用被包含在netcoreapp2.2System.Transactions.Local.dll 中, 该引用是框架库的一部分(通常默认情况下不会自动添加)。添加后,在我们想要使用它的地方添加名称空间 System.Transactions即可。代码如下所示:

在上面的代码中我们可以看到我们在创建TransactionScope实例时使用了using语句块及Disposable块,它确保了当dispose离开块并结束事务范围时调用dispose来进行资源的释放。

在一个Transaction范围中,我们可以做多个连接甚至链接到不同数据库的操作的,如下所示:

下面我们使用两个不同的数据库连接字符串来连接不同的数据库。当然我们也可以根据我们的业务要求使用尽可能多数据库。我们也可以再事务中嵌套事务。如下代码所示:

这里最顶层的事务范围称为根范围。另外这里需要注意的是即使通过调用scope.Complete()完成内部事务(上面的OtherTransaction ),如果由于各种原因无法调用rootscope complete,那么整个事务也将被回滚包括内部的事务。

*注意:执行分布式trsanctions时,您可能会收到以下异常之一*

服务器上的MSDTC不可用

已禁用分布式事务管理器(MSDTC)的网络访问。

这两个错误都是由于同样的原因,第一个是在数据库和应用程序是同一个服务器时发生的,而在另一个则是服务跟数据库分别部署在两台服务器上。对于同一台服务器,请转到run-> cmd-> services.msc。运行名为Distributed Transaction Coordinator的服务并自动启动启动类型,以便在系统重新启动时再次启动它。对于2,你可能需要参照这个链接的内容进行相应的设置

TransactionScope 类提供了多个重载构造函数,它们接受 TransactionScopeOption 类型的枚举,而该枚举定义事务范围行为。

TransactionScope对象有以下三个选项:

Required:联接环境事务,或者在环境事务不存在的情况下创建新的环境事务。

RequiresNew:成为新的根范围,也就是说,启动一个新事务并使该事务成为其自己范围中的新环境事务。

Suppress:根本不参与事务。 因此没有环境事务。

如果用 Required] 实例化范围并且存在环境事务,则该范围会联接该事务。 相反,如果不存在环境事务,该范围就会创建新的事务并成为根范围。 这是默认值。 在使用 Required时,无论范围是根范围还是仅联接环境事务,该范围中的代码都不需要有不同的行为。 该代码在这两种情况下的行为应相同。

如果用 RequiresNew 实例化范围,则它始终为根范围。 它会启动一个新事务,并且其事务成为该范围中的新环境事务。

如果用 Suppress 实例化范围,则无论是否存在环境事务,范围都从不参与事务。 始终使用此值实例化的作用域具有null作为其环境事务。

下面来让我们看一组实例代码:

在这里,我们使用不同的TransactionScopeOptions在父事务下创建了三个事务。默认情况下,范围是required ,这里父事务就是采用的这个默认参数进行创建的。它是一个创建新事务的根范围,并将其标记为环境事务。scope1也是使用required创建的,因为我们已经有了一个环境事务(范围),所以它加入到父事务中。scope2是使用RequiresNew选项创建的,这意味着它是一个独立于环境事务处理的新事务。scope3是用suppress创建的选项,这意味着它不参与任何环境事务。无论环境事务是否成功执行,它都会被执行。父(全局)范围完成后,将提交所有环境事务。

注意点

EF Core 依赖数据库提供程序以实现对 System.Transactions 的支持。 虽然支持在 .NET Framework 的 ADO.NET 提供程序之间十分常见,但最近才将 API 添加到 .NET Core,因此支持并未得到广泛应用。 如果提供程序未实现对 System.Transactions 的支持,则可能会完全忽略对这些 API 的调用。 SqlClient for .NET Core 从 2.1 及以上版本开始支持 System.Transactions。如果尝试在低版本中 如.NET Core 2.0中尝试使用该功能将引发异常。

自版本 2.1 起,.NET Core 中的 System.Transactions 实现将不包括对分布式事务的支持,因此不能使用 TransactionScope 或 CommittableTransaction 来跨多个资源管理器协调事务。主要是不依赖windows中的mstsc功能。

异步方法使用时需要注意: 在下面的例子中,我们在TransactionScope内部使用await。using(var scope = new TransactionScope()){ var groups = await Context.ProductGroups.ToListAsync()。ConfigureAwait(false); } 看起来没有问题,但它会抛出一个 System.InvalidOperationException:``A TransactionScope must be disposed on the same thread that it was created. 原因是默认情况下TransactionScope不会从一个线程切换到另一个线程。为了解决这个问题,我们必须使用 TransactionScopeAsyncFlowOption.Enabled:using(var scope = new TransactionScope(TransactionScopeAsyncFlowOption.Enabled)){ var groups = await Context.ProductGroups.ToListAsync()。ConfigureAwait(false); } 现在应该可以了吧?这取决于下面的情况。 如果我们使用和不使用TransactionScopeAsyncFlowOption这个选项的时候都使用了相同的数据库连接,并且第一次执行的时候没有使用这个选项,那么我们会得到另一个异常: System.InvalidOperationException:``Connection currently has transaction enlisted. Finish current transaction and retry. 换句话说,由于第一个访问的原因,第二个会话将会失败。如下代码所示: 想象一下,如果第一个调用是在第三方库或您正在使用的框架中完成的,二您不了解其中的代码 - 如果您之前没有看到此错误,那么你讲无从下手来解决这个问题。总结

本文带着大家熟悉了一遍TransactionScope并对其使用进行了介绍!同时介绍了在.NET Core中使用TransactionScope的一些注意事项!希望对大家有所帮助。另附上.NET Core实战项目交流群:637326624返回搜狐,查看更多

责任编辑:

.net mysql transactionscope_TransactionScope事务处理方法介绍及.NET Core中的注意事项相关推荐

  1. transactionscope 中的异步 处理 异常_.NET Core中TransactionScope事务处理方法介绍及注意事项...

    作者:依乐祝 原文链接:https://www.cnblogs.com/yilezhu/p/10170712.html 今天在写CzarCms的UnitOfWork的使用使用到了这个Transacti ...

  2. mysql 优化方法_Mysql的优化方法介绍

    本篇文章给大家带来的内容是关于Mysql的优化方法介绍,有一定的参考价值,有需要的朋友可以参考一下,希望对你有所帮助. 1.应用访问优化1).减少数据访问(Nosql作用) 2).返回更少数据 3). ...

  3. Go语言中的字符串拼接方法介绍

    本文介绍Go语言中的string类型.strings包和bytes.Buffer类型,介绍几种字符串拼接方法. 目录 string类型 strings包 strings.Builder类型 strin ...

  4. 如何更改计算机睿频,bios中关闭cpu睿频实用方法介绍

    有网友问小编关于bios中关闭cpu睿频的方法,其实cpu是一块超大规模的集成电路,是一台计算机的运算核心(Core)和控制核心( Control Unit).它的功能主要是解释计算机指令以及处理计算 ...

  5. apmserv mysql密码_apmserv中修改mysql的root与phpmyadmin密码方法介绍_PHP教程

    apmserv是一款集成的php mysql apache的应用开发环境了,安装好之后就帮我配置好了环境并且还有phpmyadmin了,下面我来介绍在修改root密码同时把phpmyadmin密码同时 ...

  6. mysql统计数据的代码_MySQL按时间统计数据的方法介绍(代码示例)

    本篇文章给大家带来的内容是关于MySQL按时间统计数据的方法介绍(代码示例),有一定的参考价值,有需要的朋友可以参考一下,希望对你有所帮助. 在做数据库的统计时,经常会需要根据年.月.日来统计数据,然 ...

  7. linux 安装mysql 8.0_Linux安装mysql 8.0的详细方法介绍(代码示例)

    本篇文章给大家带来的内容是关于Linux安装mysql 8.0的详细方法介绍(代码示例),有一定的参考价值,有需要的朋友可以参考一下,希望对你有所帮助. 经过一番努力下载mysql文件,我们可以开始M ...

  8. mysql降级_mysql8降级到mysql5的方法介绍

    本篇文章给大家带来的内容是关于mysql8降级到mysql5的方法介绍,有一定的参考价值,有需要的朋友可以参考一下,希望对你有所帮助. 最近在研究liferay的使用.liferay可以连接mysql ...

  9. mysql查看用户名_Mysql创建数据表的方法介绍(附示例)

    本篇文章给大家带来的内容是关于Mysql创建数据表的方法介绍(附示例),有一定的参考价值,有需要的朋友可以参考一下,希望对你有所帮助. 数据表是数据库最重要的组成部分之一,是其他对象的基础.如果我们的 ...

最新文章

  1. sql server 2008学习7 规范化和其他基本设计问题
  2. python函数返回多个变量_Python 3:通过多个函数返回变量
  3. acwing算法题--分组背包问题
  4. windows和linux主机名,windows和linux下如何远程获取操作系统版本和主机名
  5. Java 8流和Lambda表达式–解析文件示例
  6. struts2遍历select
  7. 【BZOJ3729】Gty的游戏,博弈+splay
  8. Python选择结构中多条件测试的简化写法
  9. [转]enable spice html5 console access in openstack kilo(centos)
  10. Hello designer|PPT笔记
  11. 匿名邮件爆迅雷看看丑闻
  12. 论文阅读笔记——Multi-Label Learning with Global and Local Label Correlation(具有全局和局部标签相关性的多标签学习)
  13. mysql组合字段语句_mysql group_concat 使用 (按分组组合字段)
  14. android metal api,Metal简述与常用API
  15. 用Windows内置工具测试硬盘速度
  16. php获取搜索记录,php如何记录搜索引擎爬行记录
  17. Mac 安装 adb 以及错误解决
  18. Unity Layout相关组件的使用,LayoutElement为主
  19. 海尔云悦2db微型计算机,家庭主机新选择 海尔云悦mini2首发评测
  20. layui基础: 弹出页面

热门文章

  1. 携程Java面试题,疯狂java讲义第三版
  2. 怎么把多张图片做成动图?一分钟教你多图合成gif
  3. python编程实现决策树算法
  4. 如何调用蓝鲸智云API接口?
  5. office2007软件下载,WPS2007免费下载
  6. linux memcached 缓存失效,高并发访问下避免对象缓存失效引发Dogpile效应
  7. 计算机硬件基础知识(一)
  8. WebApp开发:ajax请求跨域问题的解决
  9. 哪些计算机技术带来危害,电脑给我们带来了哪些危害
  10. 苹果6plus网络显示无服务器,苹果iPhone6s/6s Plus现身网络,iPhone6c去向存疑