2010-08-21 85 views
6

我看过System.Transactions命名空间,并且想知道,我是否可以使用这个名称空间的用法来创建一个RDMBS?什么是System.Transactions的实际用途?

但是当我看到一些例子时,我不明白System.Transactions是如何进行超越简单的尝试捕获并获得成功/失败结果的东西的?

这是MSDN网站上的示例,我知道它可能很简单,但我无法理解此示例中的好处,有人能告诉我下面的示例中简单try/catch和Transaction scope之间的区别。

如果我要创建一个RDBMS(创建自己的RDMBS),我知道我们必须将很多日志写到我们执行的操作的磁盘上,最后我们在回滚的情况下撤消这些操作,但是这里没有任何关于撤销任何东西。

// This function takes arguments for 2 connection strings and commands to create a transaction 
// involving two SQL Servers. It returns a value > 0 if the transaction is committed, 0 if the 
// transaction is rolled back. To test this code, you can connect to two different databases 
// on the same server by altering the connection string, or to another 3rd party RDBMS by 
// altering the code in the connection2 code block. 
static public int CreateTransactionScope(
    string connectString1, string connectString2, 
    string commandText1, string commandText2) 
{ 
    // Initialize the return value to zero and create a StringWriter to display results. 
    int returnValue = 0; 
    System.IO.StringWriter writer = new System.IO.StringWriter(); 

    try 
    { 
     // Create the TransactionScope to execute the commands, guaranteeing 
     // that both commands can commit or roll back as a single unit of work. 
     using (TransactionScope scope = new TransactionScope()) 
     { 
      using (SqlConnection connection1 = new SqlConnection(connectString1)) 
      { 
       // Opening the connection automatically enlists it in the 
       // TransactionScope as a lightweight transaction. 
       connection1.Open(); 

       // Create the SqlCommand object and execute the first command. 
       SqlCommand command1 = new SqlCommand(commandText1, connection1); 
       returnValue = command1.ExecuteNonQuery(); 
       writer.WriteLine("Rows to be affected by command1: {0}", returnValue); 

       // If you get here, this means that command1 succeeded. By nesting 
       // the using block for connection2 inside that of connection1, you 
       // conserve server and network resources as connection2 is opened 
       // only when there is a chance that the transaction can commit. 
       using (SqlConnection connection2 = new SqlConnection(connectString2)) 
       { 
        // The transaction is escalated to a full distributed 
        // transaction when connection2 is opened. 
        connection2.Open(); 

        // Execute the second command in the second database. 
        returnValue = 0; 
        SqlCommand command2 = new SqlCommand(commandText2, connection2); 
        returnValue = command2.ExecuteNonQuery(); 
        writer.WriteLine("Rows to be affected by command2: {0}", returnValue); 
       } 
      } 

      // The Complete method commits the transaction. If an exception has been thrown, 
      // Complete is not called and the transaction is rolled back. 
      scope.Complete(); 

     } 

    } 
    catch (TransactionAbortedException ex) 
    { 
     writer.WriteLine("TransactionAbortedException Message: {0}", ex.Message); 
    } 
    catch (ApplicationException ex) 
    { 
     writer.WriteLine("ApplicationException Message: {0}", ex.Message); 
    } 

    // Display messages. 
    Console.WriteLine(writer.ToString()); 

    return returnValue; 
} 

在上面的例子中,我们提交了什么?我猜SQL客户端库会做一切正确的?这是否意味着System.IO.StringWriter将包含所有成功文本或所有失败文本?或者在TransactionScope的范围之间是否存在任何锁定?

+0

你是什么意思的“使RDBMS”? – nos 2010-08-21 09:56:52

+0

关系数据库管理系统,SQL Server或MySQL或Oracle的副本,我的意思是如果我想在.net上创建自己的XYZSql数据库系统,那么我可以使用它吗? – 2010-08-21 10:03:47

+1

并非如此,但如果您的新XYZSql数据库系统支持事务,则可以在您的.NET XYZSql ADO.NET驱动程序中实现对System.Transactions的支持。 – nos 2010-08-21 10:12:29

回答

3

首先,TransactionScope与try/catch不同。 TransactionScope是由一个事务的名称范围。范围内的事务必须通过在范围上调用Complete来显式提交。任何其他情况(包括在范围中引发的异常)都会导致使用块来完成,该块将处理作用域并隐式回滚未完成的事务,但不会处理异常。

在基本情况下,来自System.Transactions的事务与db客户端事务的行为相同。 System.Transactions提供以下附加功能:

  • API不可知。您可以为oracle,sql server或web服务使用相同的事务范围。当你的事务开始于持久性无知的层(不知道持久性实现的任何信息)时,这一点很重要。
  • 自动登记。如果在连接字符串上指定(默认行为)。新的数据库连接会自动登录到现有的事务中。
  • 自动升级为分布式事务。当第二个连接进入事务处理时,它将自动提升为分配的一个(需要MSDTC)。当您争取其他协调资源(如事务性Web服务)时,促销也会有效。
1

交易将为您做必要的锁定。此外,如果事务在其范围的末尾处被处置(如果未由Complete()提交)(如评论所建议的),则存在隐式回滚。因此,如果发生异常,所有操作都会自动回滚,并且不会在数据库中发生更改。例如,如果第二个查询失败,它也会使第一个查询的更改被丢弃。

然而,对于StringWriter的,它仍然会包含一些消息,直至故障点(例如

Rows to be affected by command1: {0} 
ApplicationException Message: {0} 

既可以此代码后,会出现在你的日志。

作为创建与RDBMS如果你想真正创建一个关系数据库管理系统,我会说你可能看错了地方,如果你的意思是你想通过事务访问RDBMS,我想说,这取决于你的需求,也就是说,如果你需要交易,可以保证你的报表能够运行订单和全部或全部的方式,那么是的,交易是一个开始的好地方。

+0

是的,我打算创建RDBMS,不使用一个,我知道我可以使用数据库客户端库事务,如SqlTransaction等,但我仍然不明白你的意思是必要的锁定,因为,我看到这样,即使我不要在这里使用TransactionScope,我仍然会得到相同的结果,如果任何命令会失败的权利? – 2010-08-21 10:06:20

+0

对不起再次打扰,你的意思是即使我没有明确地在这段代码中使用SqlTransaction,System.Transactions会隐式撤消对Sql数据库所做的更改吗?这意味着Sql Client Library会自动创建一个SqlTransaction的实例并使用它,所以当我可以直接使用SqlTransaction时,实际上没有使用System.Transactions? – 2010-08-21 10:09:03

+0

TransactionScope是对SqlTransaction的一种抽象,它可以跨越SqlTransaction,e,g,MSMQ事务等其他事物。 – nos 2010-08-21 10:15:04

相关问题