关于使用Transaction对于非数据库事务的操作

在操作数据库的过程中,为了数据的一致性,我们可以使用Transaction,要么成功的时候全部提交,要么有任何一个操作失败立即全部回滚。不仅仅是在数据库方面,有时候操作其他的内容,比如说对于系统文件的操作,也需要把一些操作组合看做是一个事务。

 

现在我们看这样一个例子。现在我们需要在计算机的硬盘上创建3个目录A,B,C,要求要么3个全部创建成功,要么一个也不要创建。我们可以把这个看成是一个事务。如果我们自己写代码来操作,可以这样写。

 

[csharp] view plaincopy在CODE上查看代码片派生到我的代码片
  1. bool createA = false;  
  2. bool createB = false;  
  3. bool createC = false;  
  4.   
  5. try  
  6. {  
  7.     //这里的操作是创建3个目录  
  8.     Directory.CreateDirectory("\\A");  
  9.     createA = true;  
  10.     Directory.CreateDirectory("\\B");  
  11.     createB = true;  
  12.     Directory.CreateDirectory("\\C");  
  13.     createC = true;  
  14. }  
  15. catch (System.Exception ex)  
  16. {  
  17.     //这里在捕捉到异常时,根据运行的结果进行回滚  
  18.     if (createB)  
  19.     {  
  20.         Directory.Delete("\\B");  
  21.         Directory.Delete("\\A");  
  22.     }  
  23.     if (!createB && createA)  
  24.     {  
  25.         Directory.Delete("\\A");  
  26.     }  
  27. }  



 

但是这里我们是把这3个操作当成一个整体来回滚,及时是简单的创建删除文件夹,我们可以看到catch中的回滚逻辑已经很复杂了。可以想象,如果A,B,C这3步不仅仅是创建目录,还有一些其他的操作,那么回滚的逻辑就非常复杂,此时,我们可以考虑把这一个分成几个小事务,分开回滚。代码可以这样写,这里我们使用了Framework提供的Transactin以及TransactioScope类。

 

[csharp] view plaincopy在CODE上查看代码片派生到我的代码片
  1. class Program  
  2.     {  
  3.         static void Main(string[] args)  
  4.         {  
  5.             //这里就不需要了try catch,因为scope就已经完成了这个功能,  
  6.             //即当有异常发生向外抛的时候,会尝试跳出这个using代码块,  
  7.             //CLR会在向代码块外边跑异常之前,分别取调用每个transaction的  
  8.             //roolback方法,只要rollback中你定义的逻辑没有问题,那么所有  
  9.             //的已发生的操作就会安全的回滚。  
  10.             using (var scope = new TransactionScope())  
  11.             {  
  12.                 var A = new OperationA();  
  13.                 Transaction.Current.EnlistVolatile(A, EnlistmentOptions.None);  
  14.                 A.DoWork();  
  15.   
  16.                 OperationB B = new OperationB();  
  17.                 Transaction.Current.EnlistVolatile(B, EnlistmentOptions.None);  
  18.                 B.DoWork();  
  19.                 scope.Complete();  
  20.             }  
  21.         }  
  22.   
  23.   
  24.     }  
  25. }  
  26.   
  27. class OperationA : IEnlistmentNotification  
  28. {  
  29.     private bool _isCommitSucceed = false;  
  30.   
  31.     public void Commit(Enlistment enlistment)  
  32.     {  
  33.         enlistment.Done();  
  34.     }  
  35.   
  36.     public void DoWork()//这是自定义的方法,不是继承IEnlistmentNotification  
  37.     {  
  38.         Directory.CreateDirectory("\\A");  
  39.         //这里还有一些其他的关于A的复杂操作  
  40.         _isCommitSucceed = true;  
  41.     }  
  42.   
  43.     public void InDoubt(Enlistment enlistment)  
  44.     {  
  45.         enlistment.Done();  
  46.     }  
  47.     public void Prepare(PreparingEnlistment preparingEnlistment)  
  48.     {  
  49.         preparingEnlistment.Prepared();  
  50.     }  
  51.     public void Rollback(Enlistment enlistment)  
  52.     {  
  53.         //这里回滚A的一些操作,当然这里的操作逻辑需要你自己来写。  
  54.         //比如说查看是否创建成功,或者有一些其他的信号标记,通过这些  
  55.         //标记你来决定是删除目录还是其他的什么回滚操作。  
  56.         if (_isCommitSucceed)  
  57.             Directory.Delete("\\A");  
  58.         enlistment.Done();  
  59.     }  
  60. }  
  61.   
  62. class OperationB : IEnlistmentNotification  
  63. {  
  64.     private bool _isCommitSucceed = false;  
  65.   
  66.     public void Commit(Enlistment enlistment)  
  67.     {  
  68.         enlistment.Done();  
  69.     }  
  70.   
  71.     public void DoWork()  
  72.     {  
  73.         //这里是关于B的一些复杂操作  
  74.         throw new Exception("test");  
  75.         //这里依然有一些操作代码,但是我们模拟的是B操作途中抛出异常,所以这里的代码不会执行  
  76.     }  
  77.   
  78.     public void InDoubt(Enlistment enlistment)  
  79.     {  
  80.         enlistment.Done();  
  81.     }  
  82.     public void Prepare(PreparingEnlistment preparingEnlistment)  
  83.     {  
  84.         preparingEnlistment.Prepared();  
  85.     }  
  86.     public void Rollback(Enlistment enlistment)  
  87.     {  
  88.         if (_isCommitSucceed)  
  89.         {  
  90.             //这里回滚B的一些已经存在的操作。  
  91.         }  
  92.         enlistment.Done();  
  93.     }  


这里的机制是这样的,可能是scope.Complete()方法中有某种特别的操作,去告诉CLR这次所有的操作都顺利完成了,在跳出这个scope的时候就不用调用那些transaction的rollback方法了。如果没有执行到scope.Complete()方法,那么就会在跳出这个scope代码块的时候调用rollback方法。一般造成这个的原因是在某个transaction的逻辑操作中出现异常,造成从此次直接抛出异常跳出这个代码块,没有机会执行下边的代码。可以看出这里的重点也是写rollback的逻辑,但是相对于原来的catch中的逻辑,这里分开为多个小的逻辑,相对来说容易了很多。

这只是个人写的一种使用回滚的逻辑。在使用IEnlistmentNotification的时候,也有人把业务逻辑写入到Commit中。如果想真正理解transaction回滚的机制,建议深入理解一下TransactionScope与Transactiond的实现机制。

转载于:https://www.cnblogs.com/sky6699/p/4535760.html

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

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

相关文章

nginx管理面板_吸塑包装自建网站上线,阿里云ecs+bt面板+WordPress

吸塑包装网站搭建是我经过对比了织梦dede、帝国和WordPress后选择了WordPress,从本地搭建的apache搬迁到阿里云ecs服务器。第一步,为了后期多网站的管理,安装了宝塔面板,做了域名解析。第二步,备份所有文件和数据库。在…

linux下c 编译脚本,Linux下编译C语言与makefile脚本语言

GCC1.Source CRT 软件:可以控制linux的终端。2.FileZilla 软件: windows 远程传文件到linux.使用sourceinsight 文本编辑器一linux编译过程:C语言编译器gcc 预处理指令-E ,汇编指令-s ,编译指令 -c , 链接指…

Teamwork(The sixth day of the team)

每日列会过后,我们的工作进度都有所进展了,好开心,但是还不是我们想要的,我们想做得更快,更好。 转载于:https://www.cnblogs.com/Lingchao/p/4535939.html

微软的平板电脑_Microsoft 微软 Surface Go 2 10.5英寸二合一平板电脑(m3-8100Y、8GB、128GB、LTE) 5788元...

Microsoft 微软 Surface Go 2 英寸二合一平板电脑(m3-8100Y、8GB、128GB、LTE)【PConline 聚超值】Surface Go 2是一款主打便携的二合一产品,外观上与上代产品相比,屏幕尺寸提升为英寸,屏幕分辨率从1800*1200 增加到 1920*1280,由…

PyCharm社区版支持深度学习_深度学习,大家都看哪些社区论坛?

对代码、编程感兴趣的可以加我公众号<老K玩代码>&#xff0c;和我交流!“学习Python&#xff0c;有一半的小伙伴是冲着深度学习来的。自学虽好&#xff0c;但还是需要有人指点。那有没有什么研究深度学习的朋友比较会聚集的网络社区或平台工具呢&#xff1f;其实是有的&a…

linux 自带 mysql,linux下安装mysql

1.查看CentOS自带的mysqlrpm -qa | grep mysql2.卸载CentOS自带的mysqlrpm -e --nodeps 要卸载的软件3.下载mysql.tar将mysql压缩包通过xftp连接到linux上4.上传mysql到linuxroot登录xshell5.在/usr/local/下创建mysql文件夹&#xff0c;解压Mysql到mysql目录cd /usr/localmkdi…

石油化工设备维护检修规程_旋回破碎机横梁臂架、衬板、内外铜套检修步骤及设备检修维护要点...

旋回破碎机做为常用的头破粗碎设备&#xff0c;其突出优势就是产能高&#xff0c;破碎比大&#xff0c;可达6-9.5&#xff0c;个别情况到13.5&#xff0c;且工作平稳&#xff0c;振动小。为了保障旋回破碎机在工作时保持良好的运行状态&#xff0c;必须要加强对其日常维护与检修…

摄像头图像分析目标物体大小位置_摄像头的原理、组成、选型及应用

目录一、摄像头成像的光学原理二、摄像头模组构成以及功能原理三、摄像头名词释义四、摄像头参数解析五、摄像头选型一、摄像头成像的光学原理1.1 光学的基本定律&#xff08;1&#xff09;光线直线传播定律&#xff1a;在统一均匀介质中&#xff0c;光沿直线传播&#xff08;2…

git 合并冲突_GIT提交记录和Revert commit过程分析

一、根据GIT提交记录查看提交过程先做个git分支的背景介绍图1步骤说明1⃣️ 项目A 默认分支是 master2⃣️ 基于master分支创建 f1、f2、test分支3⃣️ f1 发起合并请求到 test分支4⃣️ f2 fetch & merge test分支 &#xff08;此时可能会有冲突&#xff09;5⃣️ &#x…

使用android-junit-report.jar导出单元测试报告

Android在使用脚本编译和测试时&#xff0c;使用默认的testrunner不会输出文件类型的单元测试报告&#xff0c;每次只能分析logcat的无法直观的看到单元测试结果和报告&#xff0c;这给编写自动化脚本带来了不少麻烦&#xff0c;虽然可以自己动手编写支持junit测试报告输出的Te…

2020.2idea创建web_使用IDEA配置Tomcat(亲测成功)

优质文章导读: XML入门(零基础教程) 一文了解Java反射 Servlet入门(零基础教程)配置环境变量打开环境变量设置,点击新建 新建两个变量CATALINA_HOME和CATELINA_BASE,变量值为Tomcat的安装路径 打开Path 添加进去刚刚创建的两个变量 IDEA中配置Tomcat创建web项目 点击 号 选择 …

linux打开另一台linux的图形化,【工具大道】ssh登录Linux服务器,并显示图形化界面...

点击关注微信公众号 "程序员的文娱情怀"分享提纲&#xff1a;1. 概述2. mac版实现ssh登录&#xff0c;显示图形化1. 概述平时ssh登录到Linux服务器都是在命令行下进行操作的&#xff0c;简单高效。但是有些时候&#xff0c;需要配置一些Linux系统下的图形化软件的参数…

c++循环执行一个函数_循环

循环目标程序的三大流程while 循环基本使用break 和 continuewhile 循环嵌套01. 程序的三大流程在程序开发中&#xff0c;一共有三种流程方式&#xff1a;顺序 —— 从上向下&#xff0c;顺序执行代码分支 —— 根据条件判断&#xff0c;决定执行代码的 分支循环 —— 让 特定代…

如何配置一个最基本的web富文本编辑器?--之wangEditor(验证成功)

第一步&#xff0c;引用wangEditor的css文件&#xff0c;css文件最好在<head>中引用 <link rel"stylesheet" type"text/css" href"css/wangEditor-1.3.0.min.css"> 第二步&#xff0c;引用jquery和wangEditor.js&#xff0c;js文件最…

地表反射率影响因素_【热岛强度可影响城市夏季降水落区】

本期嘉宾&#xff1a;北京城市气象研究院研究员 苗世光 副研究员 张亦洲采访人&#xff1a;中国气象报记者 宛霞 通讯员 楚艳丽本期观点&#xff1a;城市化对天气的影响越来越显著 &#xff0c;城市热岛强度可作为区分城市下垫面对夏季降水影响类型的重要因素。一直以来&#x…

gitlab 将管理员权限移交给ldap账户_CDPDC中Atlas集成FreeIPA的LDAP认证

文档编写目的Cloudera从CM6.3版本开始&#xff0c;引入了Red Hat IdM来做整个集群的认证&#xff0c;Red Hat IdM对应的软件为FreeIPA&#xff0c;在本文中描述如何使用FreeIPA来做CDP-DC集群的认证。关于FreeIPA服务器搭建参考<使用FreeIPA对Linux用户权限统一管理>。之…

emwin edit控制的输入长度小数点怎么处理_变频器学习,变频器主电路与控制回路学习...

一、变频器主电路的接线流程1、当我们拿到变频器&#xff0c;挤压变频器两侧凹槽&#xff0c;打开上盖&#xff0c;取下挡线板&#xff0c;变频器的R, S, T端子接电源线&#xff0c;U, V, W端子接电机线&#xff0c;地线符号处接地线。2、我们将电源线的黄、绿、红按照顺序接到…

python识别图片上的文字_Python如何识别图片中的文字 【转】

Python如何识别图片中的文字&#xff0c;这里给个案例并附上详细步骤&#xff1a;模块包的安装&#xff1a; 1、安装PIL&#xff1a;pip install Pillow 2、安装pytesser3&#xff1a;pip install pytesser3 3、安装pytesseract&#xff1a;pip install pytesseract 4、安装aut…

win10电脑桌面透明便签_在win10电脑桌面上使用工作跟进提醒办公软件可用哪个便签软件?...

每天在开展工作之前&#xff0c;您会列一个详细的计划清单吗&#xff1f;很多人为了避免工作中出现躁动不安的情绪&#xff0c;会提前制定工作跟进计划表&#xff0c;将每日的每项工作一条条记录好&#xff0c;按照计划有目的地来完成。由于在日常工作中&#xff0c;电脑是办公…

python array函数_Python 中的range()函数与array()函数

我们在Python中存在一个非常好用的range()与array()函数&#xff0c;下面作用法简要介绍。 一、range()函数 >>> range(1,10)   ——>不包括10 [1, 2, 3, 4, 5, 6, 7, 8, 9]>>>range(1,10,2)  ——>1到10&#xff0c;间隔为2(不包括10) [1, 3, 5, …