下载本文档
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
1、事务机制什么叫事务?同步发生数据更新时,防止数据的不一致。这些就是数据库特有的术语了。数据库事务是指作为单个逻辑工作单元执行的一系列操作。设想网上购物的一次交易,其付款过程至少包括以下几步数据库操作: 更新客户所购商品的库存信息 保存客户付款信息 -可能包括与银行系统的交互 生成订单并且保存到数据库中 更新用户相关信息,例如购物数量等等正常的情况下,这些操作将顺利进行,最终交易成功,与交易相关的所有数据库信息也成功地 更新。但是,如果在这一系列过程中任何一个环节出了差错,例如在更新商品库存信息时发生异常、 该顾客银行帐户存款不足等,都将导致交易失败。一旦交易失败,数据库中所有信息都必须保持交
2、易前的状态不变,比如最后一步更新用户信息时失败而导致交易失败,那么必须保证这笔失败的交 易不影响数据库的状态-库存信息没有被更新、用户也没有付款,订单也没有生成。否则,数据库的信息将会一片混乱而不可预测。数据库事务正是用来保证这种情况下交易的平稳性和可预测性的技术。数据库事务的 ACID属性事务处理可以确保除非事务性单元内的所有操作都成功完成,否则不会永久更新面向数据的资 源。通过将一组相关操作组合为一个要么全部成功要么全部失败的单元,可以简化错误恢复并使应 用程序更加可靠。一个逻辑工作单元要成为事务,必须满足所谓的ACID(原子性、一致性、隔离性和持久性)属性: 原子性事务必须是原子工作单元
3、;对于其数据修改,要么全都执行,要么全都不执行。通常,与某个 事务关联的操作具有共同的目标,并且是相互依赖的。如果系统只执行这些操作的一个子集,则可 能会破坏事务的总体目标。原子性消除了系统处理操作子集的可能性。 一致性事务在完成时,必须使所有的数据都保持一致状态。在相关数据库中,所有规则都必须应用于事务的修改,以保持所有数据的完整性。事务结束时,所有的内部数据结构(如B树索引或双向链表)都必须是正确的。某些维护一致性的责任由应用程序开发人员承担,他们必须确保应用程序 已强制所有已知的完整性约束。例如,当开发用于转帐的应用程序时,应避免在转帐过程中任意移 动小数点。 隔离性由并发事务所作的修改
4、必须与任何其它并发事务所作的修改隔离。事务查看数据时数据所处的 状态,要么是另一并发事务修改它之前的状态,要么是另一事务修改它之后的状态,事务不会查看 中间状态的数据。这称为可串行性,因为它能够重新装载起始数据,并且重播一系列事务,以使数 据结束时的状态与原始事务执行的状态相同。当事务可序列化时将获得最高的隔离级别。在此级别 上,从一组可并行执行的事务获得的结果与通过连续运行每个事务所获得的结果相同。由于高度隔 离会限制可并行执行的事务数,所以一些应用程序降低隔离级别以换取更大的吞吐量。 持久性事务完成之后,它对于系统的影响是永久性的。该修改即使出现致命的系统故障也将一直保持。DBMS的责任和
5、我们的任务企业级的数据库管理系统(DBMS )都有责任提供一种保证事务的物理完整性的机制。就常用的SQL Server2000系统而言,它具备锁定设备隔离事务、记录设备保证事务持久性等机制。因此,我们不必关心数据库事务的物理完整性,而应该关注在什么情况下使用数据库事务、事务对性能的 影响,如何使用事务等等。本文将涉及到在.net框架下使用 C#语言操纵数据库事务的各个方面。体3金SQL语言的事务机制作为大型的企业级数据库,SQL Server2000对事务提供了很好的支持。我们可以使用SQL语句来定义、提交以及回滚一个事务。如下所示的 SQL代码定义了一个事务,并且命名为"MyTra
6、nsaction"(限于篇幅,本文并不讨论如何编写 SQL语言程序,请读者自行参考相关书籍):DECLARE TranName VARCHAR(20)SELECT TranName = 'MyTransaction'BEGIN TRANSACTION TranNameGOUSE pubs GOUPDATE royschedSET royalty = royalty * 1.10WHERE title_id LIKE 'Pc%' GOCOMMIT TRANSACTION MyTransactionGO这里用到了 SQL Server2000 自带的示例数
7、据库 pubs ,提交事务后,将为所有畅销计算机书籍 支付的版税增加10%。打开SQL Server2000的查询分析器,选择 pubs数据库,然后运行这段程序,结果显而易见。可是如何在 C#程序中运行呢?我们记得在普通的SQL查询中,一般需要把查询语句赋值给SalCommand.CommandText 属性,这里也就像普通的SQL查询语句一样,将这些语句赋给SqlCommand.CommandText属性即可。要注意的一点是,其中的 "GO"语句标志着 SQL批处理的结束,编写SQL脚本是需要的, 但是在这里是不必要的。我们可以编写如下的程序来验证这个想法:/TranSq
8、l.csusing System;using System.Data;using System.Data.SqlClient;namespace Aspcnpublic class DbTranSqlfile:/将事务放到 SQL Server 中执行public void DoTran() ( file:/建立连接并打开SqlConnection myConn=GetConn();myConn.Open();SqlCommand myComm=new SqlCommand(); try (myComm.Connection=myConn;myComm.CommandText="DE
9、CLARE TranName VARCHAR(20)" myComm.CommandText+="SELECT TranName = 'MyTransaction'" myComm.CommandText+="BEGIN TRANSACTION TranName " myComm.CommandText+="USE pubs "myComm.CommandText+="UPDATE roysched SET royalty = royalty * 1.10 WHERE title_id LIKE &
10、#39;Pc%' "myComm.CommandText+="COMMIT TRANSACTION MyTransaction " myComm.ExecuteNonQuery(); catch(Exception err) (throw new ApplicationException(" 事务操作出错,系统信息:"+err.Message); finally (myConn.Close(); file:/获取数据连接 private SqlConnection GetConn()(string strSql="Data S
11、ource=localhost;Integrated Security=SSPI;user id=sa;password=" SqlConnection myConn=new SqlConnection(strSql);return myConn; public class Test (public static void Main()(DbTranSql tranTest=new DbTranSql();tranTest.DoTran();Console.WriteLine("事务处理已经成功完成。");Console.ReadLine();注意到其中的 Sql
12、Command 对象 myComm ,它的CommandText 属性仅仅是前面SQL代码字符串连接起来即可,当然,其中的 "GO"语句已经全部去掉了。这个语句就像普通的查询一样,程序 将SQL文本事实上提交给DBMS去处理了,然后接收返回的结果(如果有结果返回的话)。很自然,我们最后看到了输出"事务处理已经成功完成",再用企业管理器查看pubs数据库的roysched 表,所有title_id字段以"PC”开头的书籍的 royalty字段的值都增加了0.1倍。这里,我们并没有使用ADO.net的事务处理机制,而是简单地将执行事务的SQL语句当
13、作普通的查询来执行,因此,事实上该事务完全没有用到.net的相关特性。了解.net中的事务机制如你所知,在.net框架中主要有两个命名空间(namespace)用于应用程序同数据库系统的交互:System.Data.SqlClient 和 System.Data.OleDb 。前者专门用于连接Microsoft 公司自己的 SQLServer数据库,而后者可以适应多种不同的数据库。这两个命名空间中都包含有专门用于管理数据 库事务的类,分别是 System.Data.SqlClient.SqlTranscation 类和 System.Data.OleDb.OleDbTranscation 类。
14、就像它们的名字一样,这两个类大部分功能是一样的,二者之间的主要差别在于它们的连接机制,前者提供一组直接调用SQL Server的对象,而后者使用本机OLE DB 启用数据访问。事实上,ADO.net 事务完全在数据库的内部处理,且不受 Microsoft 分布式事务处理协调器(DTC)或任何其他事务性机制的支持。本文将主要介绍System.Data.SqlClient.SqlTranscation 类,下面的段落中,除了特别注明,都将使用System.Data.SqlClient.SqlTranscation 类。事务的开启和提交现在我们对事务的概念和原理都了然于心了,并且作为已经有一些基础的
15、C#开发者,我们已经熟知编写数据库交互程序的一些要点,即使用SqlConnection 类的对象的 Open()方法建立与数据库服务器的连接,然后将该连接赋给SqlCommand 对象的Connection 属性,将欲执行的 SQL语句赋给它的CommandText 属性,于是就可以通过SqlCommand对象进行数据库操作了。对于我们将要编写的事务处理程序,当然还需要定义一个SqlTransaction类型的对象。并且看到SqlCommand对象的Transcation 属性,我们很容易想到新建的SqlTransaction对象应该与它关联起来。基于以上认识,下面我们就开始动手写我们的第一个
16、事务处理程序。我们可以很熟练地写出下 面这一段程序:/DoTran.csusing System;using System.Data;using System.Data.SqlClient;namespace Aspcn( public class DbTran ( file:/执行事务处理 public void DoTran() ( file:/建立连接并打开 SqlConnection myConn=GetConn(); myConn.Open();SqlCommand myComm=new SqlCommand();SqlTransaction myTran=new SqlTransa
17、ction(); try ( myComm.Connection=myConn;myComm.Transaction=myTran; file:/定位到pubs数据库 myComm.CommandText="USE pubs" myComm.ExecuteNonQuery();file:/更新数据file:/将所有的计算机类图书myComm.CommandText="UPDATE roysched SET royalty = royalty * 1.10 WHERE title_id LIKE 'Pc%'"myComm.ExecuteNo
18、nQuery();/提交事务myTran.Commit(); catch(Exception err) ( throw new ApplicationException("事务操作出错,系统信息: "+err.Message); finally ( myConn.Close(); file:/获取数据连接 private SqlConnection GetConn() (string strSql="Data Source=localhost;Integrated Security=SSPI;user id=sa;password="SqlConnect
19、ion myConn=new SqlConnection(strSql); return myConn;) ) public class Testpublic static void Main() (DbTran tranTest=new DbTran();tranTest.DoTran();Console.WriteLine("事务处理已经成功完成。");Console.ReadLine();) ) )显然,这个程序非常简单,我们非常自信地编译它,但是,出乎意料的结果使我们的成就感顿 时烟消云散:error CS1501: 重载"SqlTransaction&q
20、uot; 方法未获取 "0"参数 是什么原因呢?注意到我们初始化的代码:SqlTransaction myTran=new SqlTransaction();显然,问题出在这里,事实上,SqlTransaction类并没有公共的构造函数,我们不能这样新建一个SqlTrancaction 类型的变量。在事务处理之前确实需要有一个SqlTransaction 类型的变量,将该变量关联到SqlCommand 类的Transcation属性也是必要的,但是初始化方法却比较特别一点。在初始化 SqlTransaction 类时,你需要使用SqlConnection 类的 BeginT
21、ranscation() 方法:SqlTransaction myTran; myTran=myConn.BeginTransaction();该方法返回一个SqlTransaction 类型的变量。在调用 BeginTransaction() 方法以后,所有基于该数据连接对象的SQL语句执行动作都将被认为是事务MyTran的一部分。同时,你也可以在该方法的参数中指定事务隔离级别和事务名称,如:SqlTransaction myTran;myTran=myConn.BeginTransaction(IsolationLevel.ReadCommitted,"SampleTransac
22、tion");关于隔离级别的概念我们将在随后的内容中探讨,在这里我们只需牢记一个事务是如何被启动,并且关联到特定的数据链接的。先不要急着去搞懂我们的事务都干了些什么,看到这一行: myTran.Commit();是的,这就是事务的提交方式。该语句执行后,事务的所有数据库操作将生效,并且为数据库 事务的持久性机制所保持-即使系统在这以后发生致命错误,该事务对数据库的影响也不会消失。对上面的程序做了修改之后我们可以得到如下代码(为了节约篇幅,重复之处已省略,请参照 前文):/DoTran.cs file:/执行事务处理public void DoTran()(file:/建立连接并打开SqlConnection myConn=GetCo
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 2024瓷砖铺贴工程进度控制合同
- 第13课 搭积木讲故事(1)猫和老鼠(说课稿)- 六年级上册信息技术 冀人版
- 2025年粤教新版三年级语文上册月考试卷
- 2024年北师大版选修4地理上册月考试卷
- 2025年上教版二年级数学上册阶段测试试卷
- 2025年粤教新版高三地理上册月考试卷
- 2025年岳麓版八年级地理下册月考试卷
- 2024年鲁科版九年级物理下册阶段测试试卷含答案
- 2025年鲁教版八年级物理下册阶段测试试卷含答案
- 二零二五年度国际文化交流合作协议3篇
- 2025年上海市长宁区高三语文一模作文解析及范文:激情对于行动是利大于弊吗
- 晋升管理制度(30篇)
- 2024信息技术应用创新信息系统适配改造成本度量
- 广东省广州市2025届高三上学期12月调研测试(零模)英语 含解析
- 陕西测绘地理信息局所属事业单位2025年上半年招聘87人和重点基础提升(共500题)附带答案详解
- 保险学期末试题及答案
- 高一数学上学期期末模拟试卷01-【中职专用】2024-2025学年高一数学上学期(高教版2023基础模块)(解析版)
- 严重精神障碍患者随访服务记录表
- 2024-2025学年人教版八年级上册地理期末测试卷(一)(含答案)
- 统编版(2024新版)七年级上册道德与法治第四单元综合测试卷(含答案)
- 沪教版英语小学六年级上学期期末试题与参考答案(2024-2025学年)
评论
0/150
提交评论