事务未升级为分布式事务

问题描述 投票:0回答:1

我的控制器代码类似于以下内容(此处匿名)。我预计由于 EF Core 6 中缺乏分布式事务支持而引发异常,并且由于使用两个不同的

DbConnection
和两个不同的
DbContext
,我预计代码会尝试将事务升级为分布式事务s 在同一事务中。我调试并验证了两个不同的连接具有不同的进程ID,因此它似乎与连接池无关。为什么这段代码看起来有效?

using System;
using System.Linq;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Hosting;
using Npgsql;

namespace Controllers.Test;

[Route("test")]
public sealed class TestController : ControllerBase
{
    private readonly IConfiguration _configuration;
    private readonly IHostEnvironment _host;

    public TestController(
        IConfiguration configuration,
        IHostEnvironment host)
    {
        _configuration = configuration;
        _host = host;
    }

    [HttpGet]
    public void Get()
    {
        using var transactionScope = new TransactionScope(
            TransactionScopeOption.Required,
            new TransactionOptions { IsolationLevel = IsolationLevel.ReadCommitted, Timeout = TimeSpan.FromMinutes(30) },
            TransactionScopeAsyncFlowOption.Enabled);

        var fooConnectionString = _configuration.GetConnectionString("foo")!;
        var barConnectionString = _configuration.GetConnectionString("bar")!;

        using var fooConnection = new NpgsqlConnection(fooConnectionString);
        using var barConnection = new NpgsqlConnection(barConnectionString);
        
        fooConnection.Open();
        barConnection.Open();

        using var fooDbContext = new FooDbContext(new DbContextOptionsBuilder<FooDbContext>()
            .UseNpgsql(fooConnection, o => o.UseNodaTime())
            .Options);
        using var barDbContext = new BarDbContext(new DbContextOptionsBuilder<BarDbContext>()
            .UseNpgsql(barConnection, o => o.UseNodaTime())
            .Options);

        var foo = fooDbContext.Foos.OrderBy(x => x.Id).First();
        foo.SequenceNumber++;
        fooDbContext.SaveChanges();

        var bar = barDbContext.Bars.OrderBy(x => x.Id).First();
        bar.SequenceNumber++;
        barDbContext.SaveChanges();

        transactionScope.Complete();
    }
}

.NET Core 6

Npgsql.EntityFrameworkCore.PostgreSQL 版本 6.0.7

Microsoft.EntityFrameworkCore 版本 6.0.8

c# postgresql .net-core entity-framework-core npgsql
1个回答
0
投票

您运行的 .Net Core 版本是什么?带有 .Net Core 7 的 Windows 支持分布式事务。如果您针对 .Net Core 6 进行构建,您可能会看到预期的异常。 Npgsql 可能不完全支持它们并忽略或重新使用连接,您可以尝试:

    var foo = fooDbContext.Foos.OrderBy(x => x.Id).First();
    foo.SequenceNumber++;
    var bar = barDbContext.Bars.OrderBy(x => x.Id).First();
    bar.SequenceNumber++;

    fooDbContext.SaveChanges();
    barDbContext.SaveChanges();

来自 Npgsql doco:(https://www.npgsql.org/doc/basic-usage.html)

虽然Npgsql部分支持这种机制,但由于.NET支持的一些设计问题,它没有实现分布式事务的恢复部分。虽然分布式事务可能适合您,但不鼓励使用 Npgsql 完全依赖它们。

© www.soinside.com 2019 - 2024. All rights reserved.