Skip to content

使用 TransactionScope 实现 SqlServer 的分布式事务

🏷️ C# FluentData

本来是想通过 TransactionScope 来实现分布式事务的。

ORM 使用的是 FluentData

测试代码

csharp
using (var ts = new TransactionScope())
{
    using (var db_wirte = new DbContext().ConnectionString(CONN_WRITE, new SqlServerProvider()).UseTransaction(true))
    {
        db_wirte.Insert("Table_A", new TestModel() {
            Guid = Guid.NewGuid(),
            Name = "测试数据",
            CreateTime = DateTime.Now,
            ModifyTime = DateTime.Now,
        }).AutoMap().Execute();

        using (var db_prod = new DbContext().ConnectionString(CONN_PROD, new SqlServerProvider()).UseTransaction(true))
        {
            db_prod.Insert("Table_B", new TestModel()
            {
                Guid = Guid.NewGuid(),
                Name = "测试数据",
                CreateTime = DateTime.Now,
                ModifyTime = DateTime.Now,
            }).AutoMap().Execute();

            db_prod.Commit();
        }

        db_wirte.Commit();
    }

    ts.Complete();
}

如果 SqlServer 服务器未启动 MSDTC,则会报如下错误。启用 Distributed Transaction Coordinator 服务即可。

服务器 'EDG2GYKVF8G5P6Z' 上的 MSDTC 不可用。

.NET Core 暂时还不支持分布式事务,在 .NET Core 中执行会有如下错误:

This platform does not support distributed transactions.
at Framework.Data.ExecuteQueryHandler.HandleQueryException(Exception exception) in \Framework.Data\Command\Handlers\ExecuteQueryHandler.cs:line 107
at Framework.Data.ExecuteQueryHandler.ExecuteQuery(Boolean useReader, Action action) in \Framework.Data\Command\Handlers\ExecuteQueryHandler.cs:line 28
at Framework.Data.DbCommand.Execute() in \Framework.Data\Command\PartialClasses\Execute.cs:line 9
at Framework.Data.BaseInsertBuilder.Execute() in \Framework.Data\Builders\Insert\BaseInsertBuilder.cs:line 22
at OctProdServices.Controllers.ScopeTestController.Success() in \OctProdServices\Controllers\ScopeTestController.cs:line 59

同样的代码在 .NET Framework 4.5.2 是可以运行的,说明 .NET Framework 4.5.2 是支持通过 TransactionScope 来实现分布式事务的。

根据 Transactionscope throwing exception this platform ...EF Core 2.0 TransactionScope Error 上的回答, .NET Core 不支持分布式事务是石锤了。

.NET Core doesn't support Distributed Transactions because it would require a different transaction manager on each platform. It may appear in the future, but for now any Transaction that would require two different resource managers will throw this exception.

另外在 .NET Core 的源码 DistributedTransaction.cs 中可以看到现在是 throw 一个 NotSupported 异常的。

So,通过 TransactionScope 来实现的调查只能暂时就此结束了。

.NET 测试结果

txt
执行时间(分布式事务)(共 1000 条数据):2173 ms。
执行时间(非分布式事务)(共 1000 条数据):1076 ms。
执行时间(分布式事务)(共 1000 条数据):2173 ms。
执行时间(非分布式事务)(共 1000 条数据):1077 ms。
执行时间(分布式事务)(共 1000 条数据):2180 ms。
执行时间(非分布式事务)(共 1000 条数据):1070 ms。
执行时间(分布式事务)(共 1000 条数据):3120 ms。
执行时间(非分布式事务)(共 1000 条数据):1025 ms。
执行时间(分布式事务)(共 1000 条数据):2179 ms。
执行时间(非分布式事务)(共 1000 条数据):1072 ms。