2024年10月transactionscope异常有哪些(c#分布式事务和try catch的区别)

 更新时间:2024-10-12

  ⑴transactionscope异常有哪些(c#分布式事务和trycatch的区别

  ⑵c#分布式事务和trycatch的区别

  ⑶在这里个人建议用using来创建,因为using实现了IDispose接口,它会隐式的调用TransactionScope对象的Dispose方法,即使发生异常时也是如此,能确保在事务结束或者异常的时候也能正确的释放资源。其实我们反编译一下,它的内部实现就是一个try...finally代码块,这样也就不难理解using的作用了。说主题,在某地市的某库升级中,为避免程序运行中产生脏数据以及数据更新不一致导致的重复同步情况,在可能产生上述问题的考虑下,我用这个TransactionScope来对上述的操作进行事务处理。在本机的测试环境中,运行结果是正常的,当然这个运行正常的前提是数据量较小的情况下,我每次只对一条或者十几条数据的不同表进行insert和update。然而部署到生产环境针对真实数据运行之后,发现这个事务总是回滚,一直无法正常提交。程序也就没法正常跑起来。因为生产环境中的数据有W左右,insert一次、update一次,最后再insert一条同步语句,前个操作都是比较耗时的。我切换回测试环境调试了一下,逐行运行,发现当执行完第一个insert之后,执行第二个update时发生异常了。这个异常由TransactionScope抛出,异常提示是:事务已中止。这个错误,在数据量小的情况下不会发生,数据量大一些就出现了,这个是不是和事务处理的时间长短有关呢?因为我明显感觉到在这次调试的时候,执行的时间比之前数据量只有一条的时候长了很多,至少花费分钟以上。于是google一下,验证了我的想法。TransactionScope有些重载函数是可以接受TimeSpan类型的值,这个就是事务的超时时间了。当事务实现隔离的时候,事务范围内的资源将会被锁定,如果一些事务长期占有资源,那将很容易造成死锁,为了避免这个问题,TransactionScope事务会定义一个超时限制,这个超时默认值为秒。如果事务超过此时间,即使没有发生异常,也会自动中止。上面问题的原因算是找到了,知道了原因,那么也就很好解决了。我们可以在Web.Config中配置:《configuration》

  ⑷如何:编写在单个事务范围内运行的数据库单元测试

  ⑸如果您使用此方法,则可以在测试结束之后回滚在测试过程中执行的任何更改。下面的过程说明了具体的做法:在使用BEGINTRANSACTION和ROLLBACKTRANSACTION的Transact-SQL测试脚本中创建事务。为某个测试类中的单个测试方法创建一个事务。为给定测试类中的所有测试方法创建一个事务。系统必备组件对于本主题中的某些过程,运行单元测试的计算机必须正在运行DistributedTransactionCoordinator服务。有关更多信息,请参见本主题末尾的过程。使用Transact-SQL创建事务使用Transact-SQL创建事务在数据库单元测试设计器中打开单元测试。指定要创建事务的脚本类型。例如,可以指定预先测试、测试或后期测试。在Transact-SQL器中输入测试脚本。插入BEGINTRANSACTION和ROLLBACKTRANSACTION语句,如下面的简单示例所示。此示例使用名为OrderDetails并包含行数据的数据库表:BEGINTRANSACTIONTestTransactionUPDATE“OrderDetails“setQuantity=Quantity+IFROWCOUNT!=RAISERROR(’Rowcountdoesnotequal’,,)ROLLBACKTRANSACTIONTestTransaction注意在执行MITTRANSACTION语句之后不能对事务进行回滚。有关ROLLBACKTRANSACTION如何与存储过程和触发器一起使用的更多信息,请参见Microsoft网站上的ROLLBACKTRANSACTION(Transact-SQL)。为单个测试方法创建事务在该示例中,在使用TransactionScope类型时,会使用环境事务。默认情况下,“执行连接”和“特权连接”将不使用环境事务,因为这些连接是在执行该方法之前创建的。SqlConnection具有一个EnlistTransaction方法,该方法将活动连接与某个事务相关联。环境事务在创建之后会自行注册为当前的事务,您可以通过Current属性来访问它。在该示例中,环境事务在释放之后进行回滚。如果要提交在运行单元测试时进行的任何更改,则必须调用plete方法。为单个测试方法创建事务在“解决方案资源管理器”中,右击测试项目中的“引用”节点,然后单击“添加引用”。将显示“添加引用“对话框。单击“.”选项卡。在程序集列表中,单击“System.Transactions”,然后单击“确定”。打开单元测试的VisualBasic或C#文件。包装预先测试、测试和后期测试操作,如下面的VisualBasic代码示例所示:《TestMethod()》_PublicSubdbo_InsertTableTest()UsingtsasNewSystem.Transactions.TransactionScope(System.Transactions.TransactionScopeOption.Required)ExecutionContext.Connection.EnlistTransaction(Transaction.Current)PrivilegedContext.Connection.EnlistTransaction(Transaction.Current)DimtestActionsAsDatabaseTestActions=Me.dbo_InsertTableTestData’Executethepre-testscript’System.Diagnostics.Trace.WriteLineIf((Not(testActions.PretestAction)IsNothing),“Executingpre-testscript...“)DimpretestResults()AsExecutionResult=TestService.Execute(Me.PrivilegedContext,Me.PrivilegedContext,testActions.PretestAction)’ExecutethetestscriptSystem.Diagnostics.Trace.WriteLineIf((Not(testActions.TestAction)IsNothing),“Executingtestscript...“)DimtestResults()AsExecutionResult=TestService.Execute(ExecutionContext,Me.PrivilegedContext,testActions.TestAction)’Executethepost-testscript’System.Diagnostics.Trace.WriteLineIf((Not(testActions.PosttestAction)IsNothing),“Executingpost-testscript...“)DimposttestResults()AsExecutionResult=TestService.Execute(Me.PrivilegedContext,Me.PrivilegedContext,testActions.PosttestAction)’Becausethetransactionisnotexplicitlymitted,it’isrolledbackwhentheambienttransactionis’disposed.’Tomitthetransaction,removethementdelimiter’fromthefollowingstatement:’ts.plete()EndSubPrivatedbo_InsertTableTestDataAsDatabaseTestActions注意如果使用的是VisualBasic,则除了ImportsMicrosoft.VisualStudio.TestTools.UnitTesting、ImportsMicrosoft.VisualStudio.TeamSystem.Data.UnitTesting和ImportsMicrosoft.VisualStudio.TeamSystem.Data.UnitTest.Conditions,还必须添加ImportsSystem.Transactions。如果使用的是VisualC#,则除了Microsoft.VisualStudio.TestTools、Microsoft.VisualStudio.TeamSystem.Data.UnitTesting和Microsoft.VisualStudio.TeamSystem.Data.UnitTesting.Conditions的using语句,还必须添加usingSystem.Transactions。还必须在这些程序集中添加对项目的引用。为某个测试类中的所有测试方法创建一个事务为某个测试类中的所有测试方法创建一个事务打开单元测试的VisualBasic或C#文件。在TestInitialize中创建事务,并在TestCleanup中释放它,如下面的VisualC#代码示例所示:TransactionScope_trans;posttestResults=TestService.Execute(this.PrivilegedContext,this.PrivilegedContext,testActions.PosttestAction);}启动DistributedTransactionCoordinator服务本主题中的某些过程使用System.Transactions程序集内的类型。在按照这些过程操作之前,必须确保要运行单元测试的计算机上正在运行DistributedTransactionCoordinator服务。否则,测试将失败,并出现下面的错误消息:“测试方法项目名称.测试名称.方法名称引发异常:System.Data.SqlClient.SqlException:服务器‘计算机名称’上的MSDTC不可用”。启动DistributedTransactionCoordinator服务打开“控制面板”。在“控制面板”中打开“管理工具”。在“管理工具”中打开“服务”。在“服务”窗格中,右击“DistributedTransactionCoordinator”服务,再单击“启动”。该服务的状态应当更新为“已启动”。现在应当能够运行那些使用System.Transactions的单元测试。重要事项即使您启动了分布式事务处理控制器服务,仍然可能出现以下错误:System.Transactions.TransactionManagermunicationException:workaessforDistributedTransactionManager(MSDTC)hasbeendisabled.PleaseenableDTCforworkaessinthesecurityconfigurationforMSDTCusingtheponentServicesAdministrativetool.---》System.Runtime.InteropServices.Exception:Thetransactionmanagerhasdisableditssupportforremote/worktransactions.(ExceptionfromHRESULT:xD)。如果出现此错误,您必须为网络访问配置分布式事务处理控制器。有关更多信息,请参见启用网络DTC访问。

  ⑹使用EntiryFramework操作Oracle中TransactionScope异常怎么解

  ⑺EntityFramework事务操作之TransactionScopeTransactionScope位于usingSystem.Transactions;命名空间下,需要在引用中手动加入。该类不能被继承。viewplaincopyprint?在CODE上查看代码片派生到我的代码片////摘要://使代码块成为事务性代码。此类不能被继承。publicsealedclassTransactionScope:IDisposable优点、使用起来比较方便.TransactionScope可以实现隐式的事务,使你可以在写数据访问层代码的时候不用考虑到事务,而在业务层的控制事务.、可以实现分布式事务,比如跨库或MSMQ..在EntityFramework中可以解决DbContextTransaction的多个上下文出现死锁问题。也就是说在EF中使用TransactionScope事务时,不用考虑数据库操作的多上下文问题。使用实例如下:viewplaincopyprint?在CODE上查看代码片派生到我的代码片Test_context=newTest();Test_context=newTest();using(TransactionScopetran=newTransactionScope()){try{//.修改省Areaprovince=_context.Areas.FirstOrDefault(q=》q.AreaLevel==);province.AreaName=province.AreaName+““;_context.SaveChanges();Console.WriteLine(_context.Areas.FirstOrDefault(q=》q.AreaLevel==).AreaName);//.修改市Areacity=_context.Areas.FirstOrDefault(q=》q.AreaLevel==);city.AreaName=city.AreaName+““;_context.SaveChanges();//抛出异常thrownewException(“测试事务异常“);tran.plete();}catch(Exceptionex){Console.WriteLine(“执行出错:“+ex.Message);}}特别说明:.如果你的上下文在程序中只有一个,那么如果执行事务期间出现异常,也会出现数据模型和数据库中数据不对应情况。

  ⑻ef.怎么连接mysql

  ⑼由以往的经验:在ADO.中,要操作多个数据库,那就多写两个SqlHelper吧,或封装下,能动态的修改链接字符串。因此想到在这里能不能建多个ADO.实体数据模型呢?于是乎就有了这样两个文件:SealDBModel.edmx及UcmsDBModel.edmx。SealDBModel是主要的,因此在Server中对其处理,作了继承。也同时使用了UcmsDBModel。这段代码是有问题的,当要同时操作不同数据库,且有数据有效性的时候,就会发现前面的一个成功了,后面的一个失败了。怎么办呢?EF的事务机制显然已经满足不了程序的要求了,怎么办呢?加TransactionScope吧。于是乎就有了这样一段代码:namespaceSeal_Services{publilassseal_testServer:BaseServer《seal_test》,Iseal_usersServer{publicvoidTTTT(){using(TransactionScopescope=newTransactionScope()){try{seal_testtest=newseal_test(){name=““,age=};base.AddEntity(test);base.db.SaveChanges();BaseUCMSServer《au_Role》ucmsserver=newBaseUCMSServer《au_Role》();au_Rolerole=newau_Role();role=ucmsserver.FindEntitie(c=》c.id==);role.role_name=“BBBBBBBBBBB“;ucmsserver.UpdateEntity(role);ucmsserver.db.SaveChangesForUCMS();scope.plete();}catch(System.Exceptionex){throwex;}}}}}可还是有问题呀,在处理第二个Server时会抛出异常“基础提供程序在Open上失败”。然而可以肯定的是,数据库链接字符串是正确的。可却报错了,这是为什么呢?【这是我电脑环境上的一个坑】经过分析(翻了无数百度相同的转贴后...),想到了,会不会有SQL配置相关?导致了TransactionScope的使用失败?打开SqlServerConfigurationManager时,我看到SQLServer服务,显示的是:远程过程调用失败。这个???既然失败,那就让它正确。于是:打开控制面板-卸载找到ExpressLocalDB。坚定的将其【卸载】。返回程序中,再执行。

  ⑽C#多个事务调用问题

  ⑾必须在同一个事务上下文才行如果你用TransactionScope,那没问题,如果是DbTransaction,要保证A和D共用同一个事务对象

  ⑿.方向的,同时执行两个方法,都在成功

  ⒀可以做一个返回布尔值的A方法和同样返回布尔值的B方法,如果A的返回结果是true,则执行B,如果B的返回值也是true,则提交数据库

  ⒁如何使用微软企业库对数据库的访问

  ⒂首先我们必须添加引用(dll在安装文件的目录中usingSystem.Data;usingMicrosoft.Practices.EnterpriseLibrary.Data;下面列出一些模块常用的获取数据、更新数据方法,其中有一些和直接使用ADO.中的方法很相似:方法功能ExecuteDataset,创建,加载,返回数据集LoadDataSet,加载数据到一个已经存在的数据集TransactionScope,支多项事务同时执行,一旦发生异常则会回滚所有操作填充一个数据集,使用数据集更新数据库ExecuteReader,创建,返回一个provider独立的DbDataReader实例从数据库读取多行数据ExecuteNonQuery,执行mand,返回数据库受影响的行数,可以通过output返回多个值ExecuteScalar,执行mand,返回单个值第一行第一列的值执行mand数据库命令对象ExecuteSproAessor,使用存储过程返回一个客户端可以查询的序列对象ExecuteSqlStringAessor,使用SQL语句返回一个客户端可以查询的序列对象以序列对象的形式返回数据ExecuteXmlReader,返回xml格式的数据,xmlReader类型,这个只能用在SQLServer数据库,通过SqlDatabase类调用,Database类中没有这个方法。获取xml格式数据(只能用在SQLServer数据库GetStoredProommand,返回一个存储过程的数据库mand对象GetSqlStringmand,返回一个SQL语句的数据库mand对象创建一个mand对象AddInParameter,创建一个新的input参数,并且加入mand的参数集合AddOutParameter,创建一个新的output参数,并且加入mand的参数集合AddParameter,创建一个指定类型的参数,并且加入mand的参数集合GetParameterValue,以Object类型返回指定参数的值SetParameterValue,给指定参数赋值处理mand的参数CreateConnection,创建,返回当前数据库的连接,允许你通过这个链接初始化和管理数据库事务处理数据库事务下面我们通过案例来演示以上常用的方法的使用:、首先我们来配置文件:在菜单栏中选定Blocks》AddDataSetting来添加数据库的类型和连接字符串如何使用微软企业库对数据库的访问name由应用程序访问的数据库实例的逻辑名称。在节中,名称必须是唯一的。此属性是必须的。providerName提供程序的名称。默认情况下,提供程序的名称定义在Machine.config文件中。providerName名称必须是一个在DBProviderFactory类中指定的提供程序的名称。此属性是必须的。connectionString可用于被选的提供程序的连接字符串,此属性是必须的。首先我们实例化一个DataBaseprivatestaticDatabasedb=DatabaseFactory.CreateDatabase(“Test“);.ExecuteDataset:创建,加载,返回数据集,ExecuteScalar返回单个值第一行第一列的值stringsql=“select*from“;Dbmand=db.GetSqlStringmand(sql);//执行并返回数据集rptTest.DataSource=db.ExecuteDataSet().Tables;rptTest.DataBind();如何使用微软企业库对数据库的访问.LoadDataSet,加载数据到一个已经存在的数据集privatevoidLoadDataSet(){DataSettable;stringsql=“select*from“;Dbmand=db.GetSqlStringmand(sql);Dbmand=db.GetSqlStringmand(sql);table=db.ExecuteDataSet();//执行并将所得到得结果追加的数据集table中db.LoadDataSet(,table,“table“);rptTest.DataSource=table.Tables;rptTest.DataBind();}如何使用微软企业库对数据库的访问.ExecuteReader,创建,返回一个provider独立的DbDataReader实例privatevoidExecuteReader(){stringsql=“select*from“;Dbmand=db.GetSqlStringmand(sql);IDataReaderread=db.ExecuteReader();Label.Text=“《divclass=’lefttitle’》姓名《/div》《divclass=’righttitle’》邮箱《/div》《divstyle=’clear:both;width:px’》“;while(read.Read()){//获取该列的所有信息object;read.GetValues(values);Label.Text+=“《divclass=’left’》“+values.ToString()+“《/div》“;}Label.Text+=“《/div》“;read.Close();}如何使用微软企业库对数据库的访问.ExecuteScalar,执行mand,返回单个值第一行第一列的值stringsql=“select*from“;Dbmand=db.GetSqlStringmand(sql);bl.Text=string.Format(“第一行第一列的数据:{}“,db.ExecuteScalar().ToString());如何使用微软企业库对数据库的访问.GetSqlStringmand方法用于SQL文本命令protectedvoidPage_Load(objectsender,EventArgse){select();}privatevoidgetSqlStringmand(stringsqlQuery){//GetSqlStringmand方法的使用Dbmand=db.GetSqlStringmand(sqlQuery);db.ExecuteNonQuery();select();}//为了区别添加数据跟已有数据区分开来privatestaticintID=;//插入数据protectedvoidInsert_Click(objectsender,EventArgse){getSqlStringmand(“insertvalues(’江苏迈瑞“+(ID++).ToString()+“’,“+“’)“);}//查询信息privatevoidselect(){stringsqlQuery=“select*from“;Dbmand=db.GetSqlStringmand(sqlQuery);rptGetSqlStringmand.DataSource=db.ExecuteDataSet().Tables;rptGetSqlStringmand.DataBind();}//删除信息protectedvoidbntDelete_Click(objectsender,EventArgse){getSqlStringmand(“deletewhereUserName=’江苏迈瑞“+(ID--).ToString()+“’“);}//更新数据protectedvoidupdate_Click(objectsender,EventArgse){getSqlStringmand(“updatesetUserName=’updata_江苏迈瑞’whereUserName=’测试’“);}如何使用微软企业库对数据库的访问.GetStoredProommand方法用于执行存储过程命令privatevoidgetStoredProommand(){//执行存储过程(不带参数Dbmand=db.GetStoredProommand(“proc_list“);rptGetStoredProommand.DataSource=db.ExecuteDataSet().Tables;rptGetStoredProommand.DataBind();}如何使用微软企业库对数据库的访问.参数处理(存储过程和T-Sql中的参数.Database中的GetStoredProommand方法用于执行存储过程命令。.Database中的GetSqlStringmand方法用于SQL文本命令。二个方法都返回一个Dbmand对象。(sql语句中的参数处理stringsql=“select*fromwhereID=ID“;Dbmand=db.GetSqlStringmand(sql);//添加参数db.AddInParameter(,“ID“,DbType.Int,);rptTest.DataSource=db.ExecuteDataSet().Tables;rptTest.DataBind();(存储过程中的参数处理(参数以“proc_“为存储过程)a)参数发现//直接指定参数的值,在这里要注意参数出现的顺序应与存储过程中的顺序相同。如果数据类型转换失败,则报出异常。Dbmand=db.GetStoredProommand(“proc_Test“,“测试“,);db.ExecuteNonQuery();b)处理参数AddInParameter,创建一个新的input参数,并且加入mand的参数集合AddOutParameter,创建一个新的output参数,并且加入mand的参数集合AddParameter,创建一个指定类型的参数,并且加入mand的参数集合GetParameterValue,以Object类型返回指定参数的值privatevoidGetStoredProommand(){Dbmand=db.GetStoredProommand(“proc_Login“);//设置指定参数的值、类型db.AddInParameter(,“Psd“,DbType.Int,);db.AddInParameter(,“UserName“,DbType.String,““);//获取数据库中的返回值db.AddParameter(,“retrunvalue“,DbType.String,ParameterDirection.ReturnValue,null,DataRowVersion.Current,null);db.AddOutParameter(,“outputEmail“,DbType.String,);db.ExecuteNonQuery();stringRvalue=.Parameters.Value.ToString();stringOEmail=.Parameters.Value.ToString();stringGValue=db.GetParameterValue(,“name“).ToString();lblInfo.Text=“《divclass=’lefttitle’》返回的参数为《/div》《br/》《br/》GetParameterValue=“+GValue+“《br/》AddOutParameter=“+OEmail+“《br/》ReturnValue=“+Rvalue;}存储过程ALTERprocPsdvarchar(),UserNamevarchar(),outputEmailvarchar()outputASBEGINsetoutputEmail=(SELECTEmailFROMWHEREPsd=PsdandUserName=UserName)returnrowcountEND如何使用微软企业库对数据库的访问.ExecuteSproAessor,使用存储过程返回一个客户端可以查询的序列对象privatevoidexecuteSproAessor(){varstudent=db.ExecuteSprocAessor《Student》(“proc_Test“,“江“,);Studentstd=student.ToArray();for(inti=;i《std.Count《Student》();i++){Label.Text+=std.email+““+std.username+“《br/》“;}}如何使用微软企业库对数据库的访问.ExecuteSqlStringAessor,使用SQL语句返回一个客户端可以查询的序列对象privatevoidexecuteSproAessor(){varstudent=db.ExecuteSqlStringAessor《Student》(“select*from“);Studentstd=student.ToArray();for(inti=;i《std.Count《Student》();i++){Label.Text+=std.email+““+std.username+“《br/》“;}}如何使用微软企业库对数据库的访问.ExecuteXmlReader,返回xml格式的数据,xmlReader类型,这个只能用在SQLServer数据库,通过SqlDatabase类调用,Database类中没有这个方法。privatevoidexecuteXmlReader(){stringsql=“SELECT*FROMFORXMLAUTO“;Microsoft.Practices.EnterpriseLibrary.Data.Sql.SqlDatabasesqlDB=(Microsoft.Practices.EnterpriseLibrary.Data.Sql.SqlDatabase)db;Dbmandcmd=sqlDB.GetSqlStringmand(sql);varreader=sqlDB.ExecuteXmlReader(cmd);stringxml=“《?xmlversion=’.’encoding=’utf-’?》《root》“;while(!reader.EOF){if((reader.IsStartElement())){xml+=reader.ReadOuterXml();}}xml+=“《root》“;Response.Write(xml);Response.End();}如何使用微软企业库对数据库的访问.TransactionScope支多项事务同时执行,一旦发生异常则会回滚所有操作protectedvoidTransactionScope(){//insert操作会发生失败,同时会回滚delete事件stringsqlInsert=“insertvalues(’’,’江苏迈瑞’)“;stringsqlDelete=“deletewhereID=“;try{using(TransactionScopesp=newTransactionScope(TransactionScopeOption.RequiresNew)){db.ExecuteNonQuery(mandType.Text,sqlDelete);db.ExecuteNonQuery(mandType.Text,sqlInsert);sp.plete();}}catch(Exceptionex){Response.Write(ex.Message);}}}

  ⒃请教TransactionScope实现事务,并发异常

  ⒄C#事务TransactionScopesp=newTransactionScope();try{dosth();///事务结束sp.plete();}catch{///事务回滚sp.rollback();}///事务关闭sp.close()

  ⒅哪位高手能说说Struts和iBatis

  ⒆回答:天涯客(福建)先知月日:Ibatis一下简称Ibatis包括DataAess和DataMapper两部分。整个Solution包括三个主项目:IBatis.monIBatis.DataAessIBatis.DataMapper和一个辅助项目:IBatis.mon.Logging.Log。mon项目是DataAess和DataMapper的公共基础,提供通用功能和公共服务。DataAess是DAO框架,DataMapper是SqlMap映射框架。mon.Logging.Log是对log日志服务的代理,利用log日志框架产生和输出日志。二.各项目介绍mons根目录:DataSource类封装了数据源信息,包括数据源的标志名Name,数据源的提供者Provider和数据源所代表的连接字符串ConnectionString。DataSource类有下列属性:[XmlRoot(“dataSource“,Namespa揪错┆评论┆举报

  ⒇C#中SqlTransaction与TransactionScope区别

  ⒈分布式事务处理TransactionScope?和?非分布式事务处理TransactionScope它的用途是为数据库访问提供了一个“轻量级”?区别于:SqlTransaction?的事物TransactionScope这个事务自身还封装了多个数据库查询。只要任意一个?Sqlmand?对象引发异常,程序流控制就会跳出?TransactionScope?的?using?语句块,随后,TransactionScope?将自行释放并回滚该事务。由于这段代码使用了?using?语句,所以?SqlConnection?对象和?TransactionScope?对象都将被自动调用Dispose()释放。由此可见,只需添加很少的几行代码,您就可以构建出一个事务模型,这个模型可以对异常进行处理,执行结束后会?自行清理,此外,它还可以对命令的提交或回滚进行管理。TransactionScope在文档中宣称只在“必要”情况下才提升事务级别(多数据库时才使用分布式事务,如果是同一个数据库,最好使用SqlTransaction),但是事实上不是这样。在TransactionScope内,只要你用不同的SqlConnection对象操作DB一次以上(不管你的目标是不是同一个实例、同一个库,都会提升事务级别到分布式事务。使用分布式事务注意如下几点:确保参与事务的machine开启了分布式事务支持;:如果machine开启了防火墙,需要设置msdtc进程为例外;:参与事务的machine不能跨域(如果跨域,目前微软还没有确切的解决方案;:多数据库时才使用分布式事务,如果是同一个数据库,最好使用SqlTransaction.大部分都是用SqlTransaction这个类来在程序代码中保证事务性,但是SqlTransaction是与SQL?Server数据库相关的类,如果将这个类用在了B层,那么就突破了三层架构的底线了,如果将来换数据库(比如从SQL?Server换到Oracle,D层和B层都得重写,所以这样做的局限性很大。用TransactionScope,这个类是与具体数据库无关的类,用这个类来保证B层的事务性十分可行。示例:////?《summary》????????///?发送消息?????????///?《/summary》????????///?《param?name=“sendUserId“》《/param》????????///?《param?name=“toUser“》格式FFAAF-EB---CEA|userName,FFAAF-EB---CEA|userName《/param》????????///?《param?name=“content“》《/param》????????///?《param?name=“sendedStatus“》表示已送《/param》????????///?《returns》《/returns》????????public?static?int?sendMessage(string?sendUserId,?string?toUser,?string?content,?string?sendedStatus)????????{???????????????????????int?receiveCount?=?;????????????TransactionOptions?transactionOption?=?new?TransactionOptions();????????????//设置事务隔离级别????????????transactionOption.IsolationLevel?=?System.Transactions.IsolationLevel.Readmitted;????????????//?设置事务超时时间为秒????????????transactionOption.Timeout?=?new?TimeSpan(,?,?);????????????using?(TransactionScope?scope?=?new?TransactionScope(TransactionScopeOption.Required,?transactionOption))????????????{????????????????try????????????????{????????????????????//在这里实现事务性工作?????//发送消息????????????????????insertMessage(sendUserId,?toUser,?content,?sendedStatus);?????//在接收信息表中插入记录????????????????????receiveCount?+=?insertReceiveMessage(userids,?sendUserId,?content,?““);???????????????????????????????????????//?没有错误,提交事务????????????????????scope.plete();????????????????}????????????????catch?(Exception?ex)?{????????????????????throw?new?Exception(“发送信息异常,原因:“+ex.Message);????????????????}finally{????????????????????//释放资源????????????????????scope.Dispose();??????????????????}???????????????????????????????????????????}????????????return?receiveCount;????????}

您可能感兴趣的文章:

相关文章