您好,欢迎访问三七文档
当前位置:首页 > 办公文档 > 其它办公文档 > NET开发中的事务处理大比拼
.NET开发中的事务处理大比拼事务是一组组合成逻辑工作单元的数据库操作,在系统执行过程中可能会出错,但事务将控制和维护每个数据库的一致性和完整性。事务处理的主要特征是,任务要么全部完成,要么都不完成。在写入一些记录时,要么写入所有记录,要么什么都不写入。如果在写入一个记录时出现了一个失败,那么在事务处理中已写入的其他数据就会回滚。事务可能由很多单个任务构成。简单事务的一个常见例子:把钱从A账户转到B账户,这涉及两项任务,即从A账户把钱取出来;把钱存入B账户。两项任务要么同时成功,要么一起失败,给予回滚,以便保持账户的状态和原来相同。否则,在执行某一个操作的时候可能会因为停电、网络中断等原因而出现故障,所以有可能更新了一个表中的行,但没有更新相关表中的行。如果数据库支持事务,则可以将数据库操作组成一个事务,以防止因这些事件而使数据库出现不一致。事务的ACID属性如下。原子性(Atomicity):事务的所有操作是原子工作单元;对于其数据修改,要么全都执行,要么全都不执行。原子性消除了系统处理操作子集的可能性。一致性(Consistency):数据从一种正确状态转换到另一种正确状态。事务在完成时,必须使所有的数据都保持一致。在相关数据库中,所有规则都必须应用于事务的修改,以保持所有数据的完整性。当事务结束时,所有的内部数据结构都必须是正确的。在存款取款的例子中,逻辑规则是,钱是不能凭空产生或销毁的,对于每个(收支)条目必须有一个相应的抵衡条目产生,以保证账户是平的。隔离性(Isolation):由并发事务所作的修改必须与任何其他并发事务所作的修改隔离。查看数据时数据所处的状态,要么是事务修改它之前的状态,要么是事务修改它之后的状态。简单的理解就是,防止多个并发更新彼此干扰。事务在操作数据时与其他事务操作隔离。隔离性一般是通过加锁的机制来实现的。持久性(Durability):事务完成之后,它对于系统的影响是永久性的。已提交的更改即使在发生故障时也依然存在。对于事务的开发,.NET平台也为我们提供了几种非常简单方便的事务机制。无论是在功能上还是性能上都提供了优秀的企业级事务支持。.NET开发者可以使用以下5种事务机制:SQL和存储过程级别的事务。ADO.NET级别的事务。ASP.NET页面级别的事务。企业级服务COM+事务。System.Transactions事务处理。这5种事务机制有着各自的优势和劣势,分别表现在性能、代码数量和部署设置等方面。开发人员可以根据项目的实际情况选择相应的事务机制。下面就开始分别说明日常开发中5种事务的具体使用。1.NET开发中的事务处理大比拼之SQL和存储过程级别事务2.NET开发中的事务处理大比拼之ADO.NET级别的事务3.NET开发中的事务处理大比拼之ASP.NET页面级别的事务4.NET开发中的事务处理大比拼之企业级服务COM+事务5.NET开发中的事务处理大比拼之System.Transactions.NET开发中的事务处理大比拼之SQL和存储过程级别事务数据库事务是其他事务模型的基础,当一个事务创建时不同数据库系统都有自己的规则。SQLServer默认在自动提交的模式下工作,每个语句执行完后都会立即提交;与此对照的是Oracle需要你包含一个提交语句。但是当一个语句通过OLEDB执行时,它执行完后一个提交动作会被附加上去。例如:DECLARE@TranNameVARCHAR(20);SELECT@TranName='MyTransaction';BEGINTRANSACTION@TranName;GOUSEAdventureWorks;GODELETEFROMAdventureWorks.HumanResources.JobCandidateWHEREJobCandidateID=13;GOCOMMITTRANSACTIONMyTransaction;GO或者:CREATEPROCEDURETran1asbegintransetxact_abortonInsertIntoP_Category(CategoryId,Name)values('1','test1')InsertIntoP_Category(CategoryId,Name)values('2','test2')committranGOsetxact_aborton表示遇到错误立即回滚。当然你也可以这么写:CREATEPROCEDUREtran1asbegintranInsertIntoP_Category(CategoryId,Name)values('1','test1')if(@@error0)rollbacktranelsebeginInsertIntoP_Category(CategoryId,Name)values('2','test2')if(@@error0)rollbacktranelsecommittranendGO数据库级别事务有它的优势和限制。优势:所有的事务逻辑包含在一个单独的调用中。拥有运行一个事务的最佳性能。独立于应用程序。限制:事务上下文仅存在于数据库调用中。数据库代码与数据库系统有关。.NET开发中的事务处理大比拼之ADO.NET级别的事务现在我们对事务的概念和原理都有所了解了,并且作为已经有一些基础的C#开发者,我们已经熟知编写数据库交互程序的一些要点,即:(1)使用SqlConnection类的对象的Open()方法建立与数据库服务器的连接。(2)然后将该连接赋给SqlCommand对象的Connection属性。(3)将欲执行的SQL语句赋给SqlCommand的CommandText属性。(4)通过SqlCommand对象进行数据库操作。创建一个ADO.NET事务是很简单的,需要定义一个SqlTransaction类型的对象。SqlConnection和OleDbConnection对象都有一个BeginTransaction方法,它可以返回SqlTransaction或者OleDbTransaction对象。然后赋给SqlCommand对象的Transcation属性,即实现了二者的关联。为了使事务处理可以成功完成,必须调用SqlTransaction对象的Commit()方法。如果有错误,则必须调用Rollback()方法撤销所有的操作。代码示例:基于以上认识,下面我们就开始动手写一个基于ADO.NET的事务处理程序。(示例位置:光盘\code\ch05\04\Web\WebForm2)stringconString=datasource=127.0.0.1;database=codematic;userid=sa;password=;SqlConnectionmyConnection=newSqlConnection(conString);myConnection.Open();//启动一个事务SqlTransactionmyTrans=myConnection.BeginTransaction();//为事务创建一个命令SqlCommandmyCommand=newSqlCommand();myCommand.Connection=myConnection;myCommand.Transaction=myTrans;try{myCommand.CommandText=updateP_ProductsetName='电脑2'whereId=52;myCommand.ExecuteNonQuery();myCommand.CommandText=updateP_ProductsetName='电脑3'whereId=53;myCommand.ExecuteNonQuery();myTrans.Commit();//提交Response.Write(两条数据更新成功);}catch(Exceptionex){myTrans.Rollback();//遇到错误,回滚Response.Write(ex.ToString());}finally{myConnection.Close();}ADO.NET事务的优势和限制如下。优势:简单。和数据库事务差不多快。事务可以跨越多个数据库访问。独立于数据库,不同数据库的专有代码被隐藏了。限制:事务执行在数据库连接层上,所以需要在执行事务的过程中手动地维护一个连接。注意所有命令都必须关联在同一个连接实例上,ADO.NET事务处理不支持跨多个连接的事务处理。.NET开发中的事务处理大比拼之ASP.NET页面级别的事务ASP.NET事务可以说是在.NET平台上事务实现方式最简单的一种,你仅仅需要一行代码即可。在aspx的页面声明中加一个额外的属性,即事务属性Transaction=Required,它有如下的值:Disabled(默认)、NotSupported、Supported、Required和RequiresNew,这些设置和COM+及企业级服务中的设置一样,典型的一个例子是如果你想在页面上下文中运行事务,那么要将其设置为Required。如果页面中包含有用户控件,那么这些控件也会包含到事务中,事务会存在于页面的每个地方。代码示例:页面声明Transaction=Required:%@PageTransaction=RequiredLanguage=C#AutoEventWireup=trueCodeBehind=WebForm3.aspx.csInherits=WebApplication4.WebForm3%页面引用:usingSystem.EnterpriseServices;。然后,数据操作代码:protectedvoidButton1_Click(objectsender,EventArgse){try{Work1();Work2();ContextUtil.SetComplete();//提交事务}catch(System.Exceptionexcept){ContextUtil.SetAbort();//撤销事务Response.Write(except.Message);}}privatevoidWork1(){stringconString=datasource=127.0.0.1;database=codematic;userid=sa;password=;SqlConnectionmyConnection=newSqlConnection(conString);stringstrSql=InsertIntoP_Category(CategoryId,Name)values('1','test1');SqlCommandmyCommand=newSqlCommand(strSql,myConnection);myConnection.Open();introws=myCommand.ExecuteNonQuery();myConnection.Close();}privatevoidWork2(){stringconString=datasource=127.0.0.1;database=codematic;userid=sa;password=;SqlConnectionmyConnection=newSqlConnection(conString);stringstrSql=InsertIntoP_Category(CategoryId,Name)values('2','test2');SqlCommandmyCommand=newSqlCommand(strSql,myConnection);myConnection.Open();introws=myCommand.ExecuteNonQuery();myConnection.Close();}ContextUtil是用于获取COM+上下文信息的首选类。由于此类的成员全部为static,因此在使用其成员之前
本文标题:NET开发中的事务处理大比拼
链接地址:https://www.777doc.com/doc-4409387 .html