我有一个项目,需要从服务级别创建事务并在多个存储库类中使用它。一些存储库从内部调用其子存储库。
有一个主要的管理存储库,用于管理存储库之间的一些通信(就像服务应该如何,但由于我有依赖性问题,所以决定选择这条路径)。 目前,我创建并处理来自此管理存储库的事务。但这阻碍了正确测试用例的创建。
注意:我在存储库中结合使用了 ef core 和 Dapper。并不是说这可能是一个问题,只是说而已。
这是我目前尝试过的,但由于结构的原因,我无法正确测试控制器。 这是因为当我模拟管理存储库时,我可以调用子存储库。但是当我不模拟它时,创建事务会抛出错误。
我知道有一些变通方法可以用这种结构来测试它。 但是有什么办法可以将交易处理移至专用存储库吗? 这是一个好的方法吗?
`公共类 ManagementRepo : IManagementRepo { 私有只读 MyDBContext _context; 私有 IDbContextTransaction _currentTransaction; // 仅在创建事务时初始化
public ManagementRepo(MyDBContext context /* other dependencies */)
{
_context = context;
// other initializations
}
public async Task BeginTransactionAsync()
{
_currentTransaction = await _context.Database.BeginTransactionAsync();
}
public async Task CommitTransactionAsync()
{
if (_currentTransaction != null)
{
await _currentTransaction.CommitAsync();
await _currentTransaction.DisposeAsync();
_currentTransaction = null;
}
}
public async Task RollBackTransactionAsync()
{
if (_currentTransaction != null)
{
await _currentTransaction.RollbackAsync();
await _currentTransaction.DisposeAsync();
_currentTransaction = null;
}
}
public IDbTransaction GetCurrentTransaction()
{
return _currentTransaction?.GetDbTransaction();
}
public async Task<bool> SomeMethod(/* params */)
{
var res1 = await otherRepo.SomeMethod();
var res2 = await otherRepo.SomeOtherMethod();
/*
Other logic
...
*/
// return a value or handle the result
}
} `
服务层 `public async Task UpdateService(/* 参数 */) { 等待 _ManagementRepo.BeginTransactionAsync(); 尝试 { var res = wait _ManagementRepo.SomeMethod(recordId, tableList); 如果(!res) { 抛出新的异常(“无法更新资产”); }
// Commit transaction
await _ManagementRepo.CommitTransactionAsync();
var asset = await _ManagementRepo.GetMethod(recordId);
return asset;
}
catch (Exception)
{
// Rollback in case of an error
await _ManagementRepo.RollBackTransactionAsync();
throw;
}
} `
我认为您可能想要做的是在逻辑顶层的流程模式样式中使用
TransactionScope
来包含所有单个数据库事务。
using (TransactionScope scope = new TransactionScope())
{
//do all required stuff here
...
scope.Complete();//commit top layer transaction
}
请注意,由于您很可能要在不同的连接上进行操作,事务很可能会被提升为分布式事务,所以我建议您阅读一些MSDTC和分布式事务 - https://learn .microsoft.com/en-us/previous-versions/windows/it-pro/windows-server-2008-R2-and-2008/cc771686(v=ws.10)?redirectedfrom=MSDN
这里是有关
TransactionScope
的文档 - https://learn.microsoft.com/en-us/dotnet/api/system.transactions.transactionscope