【问题标题】:TransactionScope needs DTC enabled in C# MVCTransactionScope 需要在 C# MVC 中启用 DTC
【发布时间】:2019-05-01 05:48:20
【问题描述】:

我们正在为我们的 db 使用 RDS(Amazon Relational Database Service)。我们有一些在 transactionScope 中调用的 sp。我们像这样为我们的 DBConfig 定制了 ExecutionStrategy

public class MpDbConfiguration : DbConfiguration
    {
        public MpDbConfiguration()
        {
            //SetExecutionStrategy(
            //    "System.Data.SqlClient", () => new MpExecutionStrategy(10, TimeSpan.FromMilliseconds(100)));

            SetExecutionStrategy("System.Data.SqlClient", () => SuspendExecutionStrategy
                ? (IDbExecutionStrategy)new DefaultExecutionStrategy()
                : new MpExecutionStrategy(10, TimeSpan.FromMilliseconds(100)));
        }
//.....
}

当我们有用户事务时,SuspendExecutionStrategy 设置为 True(相关文章让我使用这个 defaultStrategy:https://docs.microsoft.com/en-us/ef/ef6/fundamentals/connection-resiliency/retry-logic

问题:当我像这样运行事务时遇到这个问题

   using (var scope = new TransactionScope(TransactionScopeOption.Required, new TransactionOptions { IsolationLevel = System.Transactions.IsolationLevel.ReadCommitted }))
                {

                    if (entity != null && !string.IsNullOrEmpty(entity.EmailAddress))
                    {
                        ObjectFactory.GetInstance<IBankingService>().UnRegister(RequestContext.Current, entity);
                    }

                    Data.Configuration.MpDbConfiguration.SuspendExecutionStrategy = true;
                    Context.Current.Database.ExecuteSqlCommand("DeleteAccountByEmailAddress @usertodelete",
                                                               new SqlParameter("usertodelete", emailAddress));
                    scope.Complete();
                    Data.Configuration.MpDbConfiguration.SuspendExecutionStrategy = false;
                }
//....

这个 SP 是一个非常大的事务,但只使用一个数据库。 我得到的错误是启用 DTC。我的问题是为什么我需要 DTC

基础提供程序在打开时失败。网络访问 分布式事务管理器 (MSDTC) 已被禁用。请 在 MSDTC 的安全配置中启用 DTC 进行网络访问 使用组件服务管理工具。

实际上,这些术语对我来说是相当新的,但根据搜索,我发现 DTC 仅在我们有分布式事务时使用。万一,我们没有。

【问题讨论】:

  • DTC 也可以在同一上下文中有多个并发(嵌套)环境事务,或者当一个环境事务调用多个数据源时被调用; 调用的任何代码是否会创建TransactionScopeUnRegister 是否与数据库通信?此外,如果您只执行一个 SQL 操作 - 为什么要使用 TransactionScope - 可能只使用常规事务 - 或者,因为您似乎正在使用存储过程 - 只需让 SP 工作以原子方式,可能在内部使用事务(在调用者处没有事务)
  • @MarcGravell UnRegister 函数是对外部服务的另一个调用,它使用我们这边的数据库。据我所知,它不是多个数据源
  • @MarcGravell 就我的理解而言,transactionScope 并不总是需要启用 DTC。只是当它找到多个数据源或连接时。正确吗?
  • 此处的要求取决于 RDBMS 和数据库服务器的特定版本、客户端的操作系统以及您使用的 .NET Framework 版本。 可能不将 DTC 用于与 相同 数据源的两个连续但非并发的连接,但是:任何比这更复杂的东西通常都需要 DTC,并且在向下- anything 级别,那么即使是两个顺序(非并发)连接也可能需要 DTC

标签: .net transactions entity-framework-6 transactionscope msdtc


【解决方案1】:

一种解决方案可能是使用传统类型的事务而不是事务范围。显然那里的服务可能使用另一个上下文。我还添加了 try catch 以在出现任何异常时回滚事务。

感谢@MarcGravell 的提示。

   using (var dbContextTransaction = Context.Current.Database.BeginTransaction())
                {
                    try
                    {
                     //--- the code run inside the transaction 
                        Context.Current.SaveChanges();
                        dbContextTransaction.Commit();
                        return true;
                    }
                    catch (Exception ex)
                    {
                        dbContextTransaction.Rollback();
                       //....
                    }
                 }

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-12-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-12-23
    相关资源
    最近更新 更多