【问题标题】:TransactionScope in .NET application.NET 应用程序中的 TransactionScope
【发布时间】:2009-08-31 11:24:06
【问题描述】:

我已经编写了一个代码块来在 SQL Server 数据库中进行数据库事务。如果执行期间出现任何故障,我正在使用 TransactionScope 类回滚所有更改。 如果我在运行 SQL SERVER 的系统中运行应用程序,我没有问题。 如果我在一个系统中运行应用程序并且 SQL SERVER 在另一个系统中运行,我会收到一个错误,即 MSDTC 已禁用。

如果我在 DBServer 运行系统中启用 MSDTC,我的应用程序工作正常。

如果我必须使用 ORACLE db,系统将如何工作?我应该在 ORACLE DB 服务器上配置一些东西来启用事务范围吗?请帮帮我。

谢谢, P.Gopalakrishnan。

【问题讨论】:

    标签: .net scope transactions


    【解决方案1】:

    TransactionScope 虽然在概念上很简单,但在幕后隐藏了很多魔法。它使您能够使用分布在多台机器上的一个事务。为此,它需要来自数据库的复杂支持——而且开销可能很高,也可能不高。

    一个更简单、更有限的技术对你来说可能就足够了:DbTransaction。您的 Db 提供者可以实现语义类似于 sql 的 BEGIN TRANSACTIONCOMMIT TRANSACTION 的事务:简而言之,一个仅跨越单个机器上的单个连接的事务。

    您的代码将类似于...

    DbCommand cmd = ...;
    using (DbTransaction trans = Connection.BeginTransaction()) {
      cmd.Transaction = trans; //sometimes optional, though MS-SQL requires it.
    
      cmd.ExecuteNonQuery()
      [...other db commands with the same connection and transaction...]
      trans.Commit();
    }
    

    明确地说:您可以在事务打开时使用其他几个连接 - 但它们之间没有链接。在不同连接上执行的命令不会在事务中止时回滚(很像任意 C# 代码不会在事务中止时回滚)。

    这种方法重量更轻,粒度更细,适用于更广泛的数据库提供程序,并且不需要启动 MSDTC。另一方面,事务是特定于连接的(如果您有多个连接,它们不共享事务),它们不能被分发,并且您需要手动将命令登记到事务中(至少对于 MS -SQL)。

    注意,如果您未能在事务中登记命令,MS-SQL 将抛出异常,SQLite 仍会隐式登记命令,我不确定 oracle 是做什么的。由于无论如何必须在事务中注册所有命令,这只是一个笨拙的冗余 API,但问题不大。

    【讨论】:

      【解决方案2】:

      TransactionScope 支持(混合)快速本地事务,并可以在需要时将它们提升为更昂贵的分布式事务。对于分布式事务,需要 MSDTC。

      提升到分布式事务的一个原因是如果您在同一个 TransactionScope 中涉及第二个数据库。

      Oracle Data Provider 10.2.0.3 及更高版本支持本地事务 + 分布式事务(与 SQL Server 2005 及更高版本相同)。旧版本的 ODP.NET 仅支持分布式事务。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-06-11
        • 2018-07-02
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多