.NET:如何在System.Transactions中禁用升级?

时间:2009-10-09 08:40:25

标签: .net msdtc

是否可以在不支持分布式事务的情况下使用System.Transactions编程模型?

类似

  TransactionConfig.DisablePromotion = true;

3 个答案:

答案 0 :(得分:10)

不,您无法通过属性或配置禁用事务促销。禁用事务促销的唯一方法是避免导致事务被提升为分布式事务的条件。

要避免transaction management escalation,您需要:

  • 将SQL Server 2005或更高版本作为 你的数据库

  • 如果是SQL Server 2005,则只使用一个数据库连接 交易的生命周期。 (SQL Server 2008允许您在事务中使用多个连接而不进行升级。)

  • 仅访问一个数据库

  • 未通过您的交易 应用领域


规则的原因是确保事务的ACID properties

举个例子,让我们假设您可以指定不提升交易(如在您的代码段中)但您的代码访问两个数据库(我知道 - 您的代码仅使用一个数据库)。所以现在你已经指定不使用分布式事务,你已经启动了一个事务,并且你已经指定两个数据库都应该在这一个工作单元内。事务的ACID属性与避免分布式事务的期望之间存在冲突。在我看来,有两种方法可以解决这个问题:将事务提升为分布式事务(你说你不想这样做!)或抛出异常(因为你不能保证事务的完整性)交易)。

因此,使用DisablePromotion属性没有太大价值,因为对于不推广交易的应用程序,您仍需要遵循升级规则

如果您真的想要,可以处理DistributedTransactionStarted事件并在启动分布式事务时抛出异常。这可以保证您的应用程序不使用分布式事务,但这可能不是您想要的。

答案 1 :(得分:2)

我认为没有直接禁用促销的方法。您可能希望查看导致事务被提升的情况。 Juval Lowy写了一篇关于System.Transactions的优秀whitepaper(也可下载here)。他详细介绍了促销规则。

答案 2 :(得分:1)

我在禁用MSDTC服务的情况下使用以下代码。

var txOpts = new TransactionOptions
          {
            IsolationLevel = IsolationLevel.ReadCommitted, 
            Timeout = TimeSpan.FromMinutes(10)};

using (var tx = new TransactionScope(TransactionScopeOption.Suppress, txOpts))
{
  using (var db1 = new ObjectContext(connection1))
  {
    db1.Connection.Open();
    using (var db1tx = db1.Connection.BeginTransaction(
                                System.Data.IsolationLevel.ReadCommitted))
    {
      using (var db2 = new ObjectContext(connection2))
      {
        db2.Connection.Open();
        using (var db2tx = db2.Connection.BeginTransaction(
                          System.Data.IsolationLevel.ReadCommitted))
        {
          // do stuff

          db1.SaveChanges(false);
          db2.SaveChanges(false);

          db1tx.Commit();
          db2tx.Commit();
          tx.Complete();
        }
      }
    }
  }
}