c# - 如何针对 Azure SQL 数据库使用嵌套 TransactionScope

标签 c# azure transactions async-await msdtc

我目前正在尝试使用嵌套事务范围对 Azure SQL 数据库进行数据库访问。

我正在使用以下代码(.Net 4.5.1,我的代码一直是异步的,它是带有 EF6.1 的 ASP.Net MVC):

public async Task Test()
{
    // In my actual code, the DbContext is injected within the constructor
    // of my ASP.Net MVC Controller (thanks to IoC and dependency injection)
    // The same DbContext instance is used for the whole HttpRequest
    var context = new TestContext();

    using (var t1 = StartTransactionForAsync())
    {
        using (var t2 = StartTransactionForAsync())
        {
            context.Users.Add(new User { Name = Guid.NewGuid().ToString() });
            await context.SaveChangesAsync();

            t2.Complete();
        }
        ... // Some more code here
        t1.Complete();
    }
}

private static TransactionScope StartTransactionForAsync()
{
    return new TransactionScope(
        TransactionScopeOption.Required,
        new TransactionOptions { IsolationLevel = IsolationLevel.ReadCommitted },
        TransactionScopeAsyncFlowOption.Enabled);
}

一切都很好,除了有时 TransactionScope 升级到 MSDTC,而 Azure SQL 数据库(显然)不支持 MSDTC。所以我有时会收到以下错误:

Network access for Distributed Transaction Manager (MSDTC) has been disabled. Please enable DTC for network access in the security configuration for MSDTC using the Component Services Administrative tool.

我可以将 Enlist=False 添加到我的连接字符串中,但这会破坏上面的代码,因为即使外部 TransactionScope 内部事务仍会插入到数据库中在没有 Complete 的情况下被处置。

我的目标是单个数据库,对整个 HttpRequest 使用单个 Entity Framework 上下文始终使用相同的内容连接字符串

所以我的问题是:

  • Azure SQL 数据库是否支持嵌套事务?
  • 为什么上述代码有时会升级为 MSDTC?

official documentation说:

Microsoft Azure SQL Database does not support distributed transactions, which are transactions that affect several resources. For more information, see Distributed Transactions (ADO.NET).

Starting with the version 2.0, application transactions may be automatically promoted to distributed transactions. This applies to applications that use the System.Data.SqlClient class to perform database operations in the context of a System.Transactions transaction.

Transaction promotion occurs when you open multiple connections to different servers or databases within a TransactionScope, or when you enlist multiple connections in a System.Transactions object by using the EnlistTransaction method. Transaction promotion also occurs when you open multiple concurrent connections to the same server and database either within the same TransactionScope or by using the EnlistTransaction method.

Starting with the version 3.5, the transaction will not be promoted if the connection strings for the concurrent connections are exactly the same. For more information about transactions and avoiding transaction promotion, see System.Transactions Integration with SQL Server (ADO.NET).

这并不能回答我的任何问题。

最佳答案

尝试将其添加到您的连接字符串中,它会打开 Multiple Active Result Sets 。这应该可以解决 MSDTC 问题;尽管我对此不太确定。

MultipleActiveResultSets=True;

有关额外信息,nested transaction is not really nested transaction.

关于c# - 如何针对 Azure SQL 数据库使用嵌套 TransactionScope,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31992752/

相关文章:

c# - LINQ 比较两个列表并删除

c# - MapGet管道中的执行顺序

azure - 在 Azure 云服务辅助角色中使用本地内存进行缓存

azure - 释放 Azure Web 应用程序上的磁盘空间

c# - SET TRANSACTION ISOLATION LEVEL 仅适用于交易?

go - 如何使用 gorm 插件/钩子(Hook)将新记录插入数据库

mysql:解决隐式事务提交?

c# - Azure Active Directory 可以用作登录代理吗?

c# - 合并两个 SQLite 数据库文件 (C# .NET)

c# - AAD Graph API 权限问题