在我的.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中)意味着我无法保证跨连接的事务行为.
我考虑过的另一种选择似乎并不令人满意:
我的问题是:考虑到.NET Core中SqlConnection的当前限制,有没有办法在不使用TransactionScope的情况下编写事务装饰器?如果没有,那么下一个最好的解决方案是什么,并不会过于严重地违反单一责任原则?