c# – 试图理解TransactionScope
我正在尝试制作一个快速的虚拟应用程序,以便我可以了解System.Transactions的细节.此应用程序与2个不同的SQLExpress DB交互.如果我在组件服务中提取事务统计信息,我可以在打开第二个连接时看到在outerScope中启动事务.如果failOuter为true,则事务将中止,但不会抛出任何异常.当failInner为true时,抛出TransactionAbortedException.
基于此,我希望我的outerScope抛出TransactionAbortedException,因为我的事务统计信息每次运行我的应用程序时都会显示一个中止的事务,并将failOuter设置为true.我的方法返回true,因为即使事务中止也不会引发异常.除非我中止内部事务,否则它的行为与我期望的一样.任何澄清都将是最受欢迎的. public bool CreateNestedTransaction(bool failOuter,bool failInner) { try { using (TransactionScope outerScope = new TransactionScope()) { /* Perform transactional work here */ using (SqlConnection myConnection = new SqlConnection("server=(local)SQLExpress;Integrated Security=SSPI;database=test1")) { SqlCommand myCommand = new SqlCommand(); myConnection.Open(); myCommand.Connection = myConnection; myCommand.CommandText = "update test set Value = ((select Value from test where Id = (select max(Id) from test))+1) where Id = (select max(Id) from test)"; myCommand.ExecuteNonQuery(); } using (SqlConnection myConnection = new SqlConnection("server=(local)SQLExpress;Integrated Security=SSPI;database=test1")) { SqlCommand myCommand = new SqlCommand(); myConnection.Open(); myCommand.Connection = myConnection; myCommand.CommandText = "update test set Value = Value"; myCommand.ExecuteNonQuery(); } using (TransactionScope innerScope = new TransactionScope()) { using (SqlConnection myConnection = new SqlConnection("server=(local)SQLExpress;Integrated Security=SSPI;database=test2")) { SqlCommand myCommand = new SqlCommand(); myConnection.Open(); myCommand.Connection = myConnection; myCommand.CommandText = "update test set Value = ((select Value from test where Id = (select max(Id) from test))+1) where Id = (select max(Id) from test)"; myCommand.ExecuteNonQuery(); } if (failInner == false) { innerScope.Complete(); } } if (failOuter == false) { outerScope.Complete(); } } } catch (TransactionAbortedException) { return false; } return true; } 解决方法
通常,在TransactionScope超出范围并被处置之前,无法调用TransactionScope.Complete()而引发异常.该交易将悄然回滚.
在您的情况下发生异常是因为您尝试在外部TransactionScope上调用Complete并且它无法正确完成,因为内部TransactionScope已经失败 – 因此这会引发异常. 那有意义吗? 如果要在外部事务中止时执行某些操作,可以尝试这样的操作: // Inside each using TransactionScope(),hhok up the current transaction completed event Transaction.Current.TransactionCompleted += new TransactionCompletedEventHandler(Current_TransactionCompleted); // handle the event somewhere else void Current_TransactionCompleted(object sender,TransactionEventArgs e) { // check the status of the transaction if(e.Transaction.TransactionInformation.Status == TransactionStatus.Aborted) // do something here } 虽然我认为一般用法的清晰模式总是在TransactionScope中调用Complete()并处理任何结果异常,如果你想在事务失败时做一些特定的事情. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |