小编Mat*_*att的帖子

没有TransactionScope的.Net核心事务修饰器

在我的.NET Core应用程序中,我有一个装饰器类,我希望通过在TransactionScope中包装数据库命令的执行来处理事务.不幸的是,似乎支持TransactionScope不会通过.NET Core 2的发布进入SqlConnection:https://github.com/dotnet/corefx/issues/19708:

在缺少TransactionScope的情况下,我不确定解决此问题的最佳方法.使用TransactionScope,我的事务装饰器如下所示:

public class TransactionCommandHandlerDecorator<TCommand> : ICommandHandler<TCommand>
{
    private readonly ICommandHandler<TCommand> decorated;

    //constructor        

    public void Handle(TCommand command)
    {  
       using (var scope = new TransactionScope())
       {
           this.decorated.Handle(command);

           scope.Complete();
       }
    }
}
Run Code Online (Sandbox Code Playgroud)

目前,ICommandHandler的每个实现都获取了我的DapperContext类的实例,并处理如下命令:

public void Handle(UpdateEntity command)
    {
        var sql = Resources.UpdateEntityPart1;

        this.context.Execute(sql, new
        {
           id = command.Id;             
        });

        var sql = Resources.UpdateEntityPart2;

        //call Execute again
    }
Run Code Online (Sandbox Code Playgroud)

DapperContext类有一个连接工厂,为每次调用Execute方法提供新的连接.因为命令处理程序可能必须为单个TCommand执行多个数据库写入,所以我需要能够在出现故障时回滚.必须在我创建连接的同时创建事务(在DapperContext中)意味着我无法保证跨连接的事务行为.

我考虑过的另一种选择似乎并不令人满意:

  1. 在命令处理程序级别管理连接和事务,然后将该信息传递给dapper上下文.这样,给定命令的所有查询都使用相同的连接和事务.这可能有用,但我不喜欢给我的命令处理程序加负担这个责任的想法.在整体设计方面,似乎更自然的是DapperContext是担心连接的地方.

我的问题是:考虑到.NET Core中SqlConnection的当前限制,有没有办法在不使用TransactionScope的情况下编写事务装饰器?如果没有,那么下一个最好的解决方案是什么,并不会过于严重地违反单一责任原则?

.net transactions .net-core

5
推荐指数
1
解决办法
1038
查看次数

标签 统计

.net ×1

.net-core ×1

transactions ×1