首页 > 编程语言 >C#事务的使用

C#事务的使用

时间:2022-10-14 01:45:07浏览次数:47  
标签:事务 管理器 C# 数据库 TransactionScope 使用 RM 分布式

https://blog.csdn.net/VisageNocturne/article/details/112094795

http://t.zoukankan.com/SmilePastaLi-p-6824387.html

https://www.w3xue.com/exp/article/20225/79298.html

使用方法:

//加入事务
using (System.Transactions.TransactionScope ts = new System.Transactions.TransactionScope(System.Transactions.TransactionScopeOption.Required, new TimeSpan(12000000000)))
{
//todo
ts.Complete();
}

一、事务的定义

所谓事务,它是一个操作集,这些操作要么都执行,要么都不执行。它是一个不可分割的工作单位。

典型的例子:
网上银行系统的账户A转账到账户B,经过两个阶段:
1、从账户A取出款项
2、把款项放入账户B中
这两个过程要么同时成功,要么同时失败。
这一系列的操作就被称为事务性操作。

在一个事务性操作的环境下,操作有着以下的4种特性,被称为ACID特性。

1、原子性(Atomicity): 当事务结束,它对所有资源状态的改变都被视为一个操作,这些操作要不同时成功,要不同时失败。
2、一致性(Consistency): 操作完成后,所有数据必须符合业务规则,否则事务必须中止。
3、隔离性(Isolation): 事务以相互隔离的方式执行,事务以外的实体无法知道事务过程中的中间状态。
4、持久性(Durable): 事务提交后,数据必须以一种持久性方式存储起来。

二、事务管理器

在软件系统当中可以看到无论在数据库、Web服务、WCF、文件系统都存在着数据参与到事务运作当中,我们把管理这些数据的工具称为资源管理器RM(Resources Manager)。而事务管理器TM(Transaction Manager)就是协调多个资源管理器的工作,保证数据完整性的工具。

由上图可以看到事务的管理流程,系统通知事务管理器TM来启动事务,事务管理器TM控制向多个资源管理器RM并协调RM之间的事务操作。图中存在两个持久化RM,分别管理数据库和文件系统,这些事务操作要不同时成功,要不同时失败。

事务管理器一般分为三类:
1、轻量级事务管理器(LTM)
2、核心事务管理器(KTM)
3、分布式事务协调器(DTC)。

1、 轻量级事务管理器 (LTM)
  它是包括在 System.Transactions 命名空间内的一个事务管理框架,它只能管理单个应用程序域内的事务。LTM 可以管理多个易变的RM,但只能管理一个持久化RM。若事务试图加入第二个持久化RM,那轻量级事务管理器LTM将提升级别。LTM是性能最高的事务管理器,在可选择的情况下应该尽可能地使用 LTM 事务管理器。
  这里易变RM是指它参与会引发 “未确定状态” 的2PC事务的时候,不需要恢复服务,更多时候,易变RM的数据只存储在内存当中。
  而持久化RM是指它参与会引发 “未确定状态” 的2PC事务的时候,它需要恢复服务,持久化RM管理的数据是在于硬盘当中。所以,参与2PC事务的的持久RM必须有新旧两个版本,如果事务引发 “未确定状态” 的时候,那么它就会联系持久化RM,恢复到其中一个版本。
2PC说明 (http://blogs.msdn.com/b/diegumzone/archive/2006/08/14/699219.aspx)  
  2PC 是2 Phase Commit的缩写,代表事务的2阶段提交验证算法:在数据提交时,第一阶段:应用程序记录每个数据源并执行更新请求,TM通知每个RM来执行分布式事 务,然后每个RM都对数据执行本地的事务,在事务将提交前,TM会与各个RM进行信息交换,以获知更新是否成功。第二阶段,如果其中任何一个RM表示更新 失败,TM就会通知所有的RM事务操作失败,实现数据回滚。如果所有RM的操作都成功,那么整个TM事务就宣告成功。  
2、 核心事务管理器 (KTM)
  KTM是用于Windows Vista和Windows Server 2008 系统中的轻量级事务管理器,与LTM相像,它可以管理多个易变的RM,但只能管理一个持久化RM。
3、 分布式事务协调器(DTC)
  分布式事务协调器DTC(Distributed Transaction Coordinator)能管理多个持久化RM中的事务,事务可以跨越应用程序域、进程、硬件、域等所有的边界。在Windows Server 2008当中,DTC支持OleDB、XA、WS-AtomicTransaction、WSCoordination、WS-BusinessActivity等多个协议。由于分布式事务需要在多个参与方之间实现多次通讯,所以是一种巨大的开销,因此,在可以使用LTM和KTM的时候,应该尽量避免使用DTC。在上面图片中的事务同时启动了两个RM分别处理数据库数据与文件数据,当中启动的就是DTC分布式事务。

C#中的事务TransactionScope

(隐式事务,推荐)

一、TransactionScope的优点


1、使用起来比较方便.TransactionScope可以实现隐式的事务,使你可以在写数据访问层代码的时候不用考虑到事务,而在业务层的控制事务.

2、可以实现分布式事务,比如跨库或MSMQ.

二、TransactionScope缺点

1、性价比不高.比如,你只是在"Scope"里控制一个库的事务.用"TransactionScope"就有点浪费了.
2、一般情况下只要你使用"TransactionScope",都要配置MSDTC,要配防火墙,要开139端口.这个端口不可以更改

三、TransactionScope事务级别

在TransactionScope中默认的事务级别是Serializable,即在事务过程中,完全性锁表。别的进程不能查询,修改,新增,删除。这样会导致效率大大降低,虽然数据完整性很高。通常我们不需要那么高的数据完整性。所以需要修改默认的事务级别。

四、在C#中使用TransactionScope类(分布式事务),则须注意如下事项

1、在项目中引用using System.Transactions命名空间(先要在添加net组件的引用);

2、对MSDTC组件设置:

在控制面板--->管理工具--->服务 中,开启Distributed Transaction Coordinator 服务。


a、控制面板->管理工具->组件服务->计算机->我的电脑->右键->属性
b、选择MSDTC页, 确认"使用本地协调器"
c、点击下方"安全配置"按钮
 

d、勾选: "允许网络DTC访问","允许远程客户端","允许入站","允许出站","不要求进行身份验证".
e、对于数据库服务器端, 可选择"要求对呼叫方验证"
f、勾选:"启用事务Internet协议(TIP)事务"。
g、在双方防火墙中增加MSDTC.exe例外
可用命令行: netsh firewall set allowedprogram %windir%/system32/msdtc.exe MSDTC enable

3、重启IIS服务器。

注意:

我们只要确保数据库的打开操作是在事务范围内打开就行了。这样就可以做到事务的正确操作。

如果WEB服务器和数据库是在同一台服务器上,TransactionScope使用的是本地事务,这时不需要配置MSDTC。

如果WEB服务器和数据库不在同一台服务器上,TransactionScope会自动提升事务级别为分布式事务,这时就需要配置MSDTC。

.NET开发者用到的5种事务机制:

  • SQL和存储过程级别的事务。(数据库事务)
  • ADO.NET级别的事务。
  • ASP.NET页面级别的事务。
  • 企业级服务COM+事务。
  • System.Transactions 事务处理。

    二、数据库事务

    数据库事务是指作为单个逻辑工作单元执行的一系列操作。

    设想网上购物的一次交易,其付款过程至少包括以下几步数据库操作:

      · 更新客户所购商品的库存信息

      · 保存客户付款信息--可能包括与银行系统的交互

      · 生成订单并且保存到数据库中

      · 更新用户相关信息,例如购物数量等等

    正常的情况下,这些操作将顺利进行,最终交易成功,与交易相关的所有数据库信息也成功地更新。但是,如果在这一系列过程中任何一个环节出了差错,例如在更新商品库存信息时发生异常、该顾客银行帐户存款不足等,都将导致交易失败。一旦交易失败,数据库中所有信息都必须保持交易前的状态不变,比如最后一步更新用户信息时失败而导致交易失败,那么必须保证这笔失败的交易不影响数据库的状态--库存信息没有被更新、用户也没有付款,订单也没有生成。否则,数据库的信息将会一片混乱而不可预测。

    数据库事务正是用来保证这种情况下交易的平稳性和可预测性的技术。

    1、不同数据库的事务规则

    数据库事务是其他事务模型的基础,当一个事务创建时不同数据库系统都有自己的规则。

    • SQL Server默认在自动提交的模式下工作,每个语句执行完后都会立即提交;
    • Oracle则需要你包含一个提交语句。
    • 当一个语句通过OLE DB执行时,它执行完后一个提交动作会被附加上去。

    例如:SQL Server数据库T-SQL语句中显示指定事务

    1. declare @TranName varchar(20);
    2. select @TranName = 'MyTransaction';
    3.  
    4. begin transaction @TranName;
    5. go
    6.  
    7. use AdventureWorks;
    8. go
    9.  
    10. delete from AdventureWorks.HumanResources.JobCandidate where JobCandidateID = 13;
    11. go
    12.  
    13. commit transaction MyTransaction;
    14. go

    或在存储过程中使用

    1. create procedure Tran1
    2. as
    3. begin tran;
    4. set xact_abort on; --set xact_abort on表示遇到错误立即回滚。
    5. insert into P_Category ( CategoryId, Name ) values ( '1', 'test1' );
    6. insert into P_Category ( CategoryId, Name ) values ( '2', 'test2' );
    7. commit tran;
    8. go

      三、ADO.Net事务

      ADO.Net事务为System.Data.Common.DbTransaction类的各种派生类。ADO.Net事务不是分布式事务,不支持跨多个连接,它总是关联到一个连接上的本地事务上。

      ADO.NET 显式事务占用资源少、速度快,但功能简单,只能管理单一对象和单一持久资源间的事务。

      1. using (SqlConnection conn = new SqlConnection(ConfigurationManager.ConnectionStrings["MySqlServer"].ConnectionString))
      2. {
      3. conn.Open();
      4. using (SqlTransaction tran = conn.BeginTransaction())
      5. {
      6. using (SqlCommand cmd = new SqlCommand())
      7. {
      8. cmd.Connection = conn;
      9.  
      10. cmd.Transaction = tran;
      11. cmd.CommandType = CommandType.Text;
      12. try
      13. {
      14. cmd.CommandText = "insert into TranTable(Priority) values(1)";
      15. cmd.ExecuteNonQuery();
      16. cmd.CommandText = "insert into TranTable(Priority) values(256)";
      17. cmd.ExecuteNonQuery();
      18. tran.Commit();
      19. Response.Write("Ok");
      20. }
      21. catch (SqlException ex)
      22. {
      23. tran.Rollback();
      24. Response.Write("Error:" + ex.Message);
      25. }
      26. }
      27. }
      28. conn.Close();
      29. }

 

标签:事务,管理器,C#,数据库,TransactionScope,使用,RM,分布式
From: https://www.cnblogs.com/Dongmy/p/16789113.html

相关文章

  • [Typescript] 47. Medium- StartsWith
    Implement StartsWith<T,U> whichtakestwoexactstringtypesandreturnswhether T startswith UForexampletypea=StartsWith<'abc','ac'>//expected......
  • [Typescript] 48. Medium - EndsWith
    Implement EndsWith<T,U> whichtakestwoexactstringtypesandreturnswhether T endswith UForexample:typea=EndsWith<'abc','bc'>//expectedtob......
  • IIS 绿盟检测到HOST头攻击漏洞的解决: web应用使用SERVER_NAME而非host header。
    https://blog.csdn.net/fightingintherain/article/details/1256648851、漏洞描述2、修复方案(IIS服务端) 1)下载安装url重写工具(官网URLRewrite:TheOfficialMic......
  • CF437D The Child and Zoo
    CF437DTheChildandZoo-洛谷|计算机科学教育新生态(luogu.com.cn)很像货车运输?但是点权?转化一下。每条边\((u,v)\)设定边权为\(\min(a[u],a[v])\),那么一条简......
  • JavaScript--数据结构
     01.为什么使用数组<!DOCTYPEhtml><htmllang="en"><head><metacharset="UTF-8"><title>为什么使用数组</title></head><body><script>//保存......
  • Codeforces Round #827 (Div. 4) A - G
    A.Sumvoidsolve(){inta[3]={};cin>>a[0]>>a[1]>>a[2];sort(a,a+3);if(a[2]==a[0]+a[1])cout<<"YES\n";elsecout<<"NO......
  • 【算法训练营day2】LeetCode977. 有序数组的平方 209. 长度最小的子数组 59. 螺旋矩阵
    【算法训练营day2】LeetCode977.有序数组的平方209.长度最小的子数组59.螺旋矩阵IILeetCode977.有序数组的平方题目链接:977.有序数组的平方初次尝试上来看到建......
  • SharedWorker使用总结
    最近有个需求要在浏览器页签之间实现信息共享,由第三方包处理。看过人家的效果介绍,嚯哦,闪瞎我的双眼!没见识过的技术,怎么也得看一看呀......
  • moment使用方法
    引入:<scriptsrc="https://cdn.bootcdn.net/ajax/libs/moment.js/2.29.4/locale/af.js"></script>格式化期moment().format('MMMMDoYYYY,h:mm:ssa');//三月3日......
  • Echart使用
    EChart目录目录EChart官网导入大体架构视图大小官网https://echarts.apache.org/zh/index.html导入<scriptsrc="https://cdn.bootcdn.net/ajax/libs/echarts/5.3......