在这种情况下处理异常的最佳方法是什么

时间:2020-07-16 08:54:59

标签: c# asp.net-core exception design-patterns jira-rest-api

我正在编写一个C#WEB API,该API使用多部分形式的数据来在DB中创建记录并将文件上传到某个位置。作为创建的一部分,我还将创建一个Jira Issue并使用JIRA详细信息更新创建的记录。

  [Route("api/request/create")]
  [Consumes("multipart/form-data")]
  public async Task<HttpResponseMessage> CreateRequest()
  {
     try
     {
        var multipartMemoryStream = await Request.Content.ReadAsMultipartAsync();
        var newRequestData = await multipartMemoryStream.Contents[0].ReadAsStringAsync();

       CreateRequestCommand createRequestCommand = JsonConvert.DeserializeObject<CreateRequestCommand>(newRequestData);

       var requestId = CreateRequestInDB(createRequestCommand)
       var jira = await CreateJira(createContentRequestCommand);
       await WriteSourceFiles(multipartMemoryStream.Contents);
       await UpdateRequestWithJiraDetails(requestId, jira);
       return new SuccessResponse(requestId)
    }
   catch (Exception ex)
   {
      throw ex;
   }
}

在大多数情况下,这可以正常工作。我如何以最佳方式处理异常,以便如果任何方法失败,系统都不应将记录保留在DB中,也不要删除JIRA问题。 如果任何一个步骤失败,则将系统保持在一致状态的最佳策略是什么。

2 个答案:

答案 0 :(得分:0)

如果您有多项操作,并且希望它们全部成功或全部失败,那么您需要一个称为Transaction的概念。

在.NET中,这是在System.Transactions命名空间中实现的,类TransactionScope可能最终会用到。

很抱歉,这是模糊的,没有代码示例,但是由于您仅发布了自己的方法名称,因此您将不得不自己弄清楚,这些方法中实际执行的代码能做什么以及如何与Microsoft类。如果您的数据库是Entity Framework或纯SqlConnection,它可能是开箱即用的。但这取决于您自己。

答案 1 :(得分:0)

如果您在WikiPedia中查看Distributed transaction的定义,那么它会显示以下内容:

分布式事务是其中涉及两个或更多网络主机的数据库事务。通常,主机提供事务资源,而事务管理器负责创建和管理包含针对此类资源的所有操作的全局事务。与其他任何事务一样,分布式事务必须具有所有四个ACID(原子性,一致性,隔离性,持久性)属性,其中原子性保证工作单元(操作包)的全部或全部结果。

即使定义着重于数据库的相关性,即使您希望将数据库和文件作为工作单元来编写,该示例也适用。如果它们中的任何一个失败,则它们都应回滚。

在.NET只能在Windows操作系统上运行的年代,.NET可以利用Transaction Manager的优势。您要做的只是为两阶段提交的implement IEnlistmentNotification接口。该界面公开了4 methods

  • Prepare进行投票
  • Commit寻找幸福的道路
  • Rollback带来不幸之路
  • InDoubt在第二阶段

最后,您必须通过以下调用将该授权注册到TransactionManager:Transaction.Current.EnlistVolatile

.NET Core does not support分布式事务。也许.NET 5 ...

2相提交(和3PC)协议存在阻塞问题(123),在某些情况下它可能会卡住而无法继续。 Martin Kleppmann's Designing Data-Intensive Applications这本书以一种非常容易消耗的方式详细描述了问题。


用微服务这个词推荐的方法是Sagas pattern。您拥有所有ACID担保的本地交易。参与者之间需要某种协调。可以由协调员负责整个流程,而参与者之间彼此不了解。或者,参与者可以组成编舞,其中每个参与者都知道如何与上一个和下一个参与者进行交流。

万一发生故障,您可以回滚或应用补偿操作以撤消上一个操作的影响。有几个非常好的资源,其中所有这些都进行了详细介绍。我推荐Chris Richardson's Microservices Patterns书。有关在线入门,请阅读this article

如果您想了解一个真实的例子,那么我建议您阅读Jimmy Bogard's excellent blog series

相关问题