C# 在这种情况下,处理异常的最佳方法是什么
我正在编写一个C#WEB API,它采用多部分表单数据在DB中创建一个记录,并将文件上载到一个位置。作为创建的一部分,我还创建了一个Jira问题,并使用Jira详细信息更新创建的记录C# 在这种情况下,处理异常的最佳方法是什么,c#,asp.net-core,exception,design-patterns,jira-rest-api,C#,Asp.net Core,Exception,Design Patterns,Jira Rest Api,我正在编写一个C#WEB API,它采用多部分表单数据在DB中创建一个记录,并将文件上载到一个位置。作为创建的一部分,我还创建了一个Jira问题,并使用Jira详细信息更新创建的记录 [Route("api/request/create")] [Consumes("multipart/form-data")] public async Task<HttpResponseMessage> CreateRequest() {
[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;
}
}
[路由(“api/请求/创建”)]
[使用(“多部分/表单数据”)]
公共异步任务CreateRequest()
{
尝试
{
var multipartMemoryStream=wait Request.Content.ReadAsMultipartAsync();
var newRequestData=await multipartMemoryStream.Contents[0]。ReadAsStringAsync();
CreateRequestCommand CreateRequestCommand=JsonConvert.DeserializeObject(newRequestData);
var requestId=CreateRequestInDB(createRequestCommand)
var jira=等待CreateJira(createContentRequestCommand);
等待写入资源文件(multipartMemoryStream.Contents);
使用jiradetails(requestId,jira)等待更新请求;
返回新的SuccessResponse(requestId)
}
捕获(例外情况除外)
{
掷骰子;
}
}
这在大多数情况下都很有效。如何以最佳方式处理异常,以便在任何方法失败时,系统不应在DB中保留记录并删除JIRA问题。
如果任何一个步骤失败,那么保持系统处于一致状态的最佳策略是什么。如果您有多个操作,并且希望它们要么全部成功,要么全部失败,那么您需要一个称为a的概念 在.NET中,这是在
System.Transactions
命名空间中实现的,该类可能就是您最终使用的类
很抱歉,这是含糊不清的,没有代码示例,但由于您只发布了自己的方法名称,因此您必须自己弄清楚,这些方法中实际执行的代码是什么,以及它与Microsoft类的关系如何。如果您的数据库是实体框架或普通的
SqlConnection
,那么它可能是现成的。但这取决于你自己。如果你有多个操作,你想让它们要么全部成功,要么全部失败,那么你需要一个称为a的概念
在.NET中,这是在System.Transactions
命名空间中实现的,该类可能就是您最终使用的类
很抱歉,这是含糊不清的,没有代码示例,但由于您只发布了自己的方法名称,因此您必须自己弄清楚,这些方法中实际执行的代码是什么,以及它与Microsoft类的关系如何。如果您的数据库是实体框架或普通的
SqlConnection
,那么它可能是现成的。但这取决于你自己。如果你在维基百科上找到这个词的定义,那么它会说:
分布式事务是涉及两个或多个网络主机的数据库事务。通常,主机提供事务性资源,而事务管理器负责创建和管理包含针对此类资源的所有操作的全局事务。分布式事务与任何其他事务一样,必须具有所有四个ACID(原子性、一致性、隔离性、持久性)属性,其中原子性保证工作单元(操作包)的所有或无结果
即使定义侧重于数据库相关性,但即使您希望将数据库和文件作为一个工作单元来编写,该示例也适用。如果其中一个失败,那么两个都应该回滚
在.NET只能在Windows操作系统上运行的那些日子里,.NET可以利用。您所要做的就是使用IEnlistmentNotification
接口进行两阶段提交。该接口公开了:
准备投票
快乐路径提交
用于不愉快路径Rollback
在第二阶段InDoubt
Transaction.Current.EnglistVolatile
分布式事务。也许.NET5
2阶段提交(和3PC)协议存在阻塞问题(,),可能在某些情况下无法继续。这本书以一种非常容易理解的方式详细描述了这个问题
用微服务的话来说,推荐的方法是。您拥有所有ACID担保的本地交易。需要的是参与者之间的某种协调。可能会有协调人负责整个流程,而参与者彼此并不了解。或者,参与者可以组成一个舞蹈,每个参与者都知道如何与前一个和下一个参与者交流 如果失败,您可以回滚或应用补偿操作以撤消上一操作的效果。有几个非常好的资源,所有这些都有详细的介绍。我推荐这本书。在线入门阅读
如果你想看一个真实世界的例子,那么我建议你读一读。如果你在维基百科上找到这个例子的定义,那么它会说: 分布式事务是涉及两个或多个网络主机的数据库事务。通常,主机提供事务性资源,而事务管理器负责创建和管理包含针对此类资源的所有操作的全局事务。分布式事务与任何其他事务一样,必须具有所有四个ACID(原子性、一致性、隔离性、持久性)属性,其中原子性保证工作单元(操作包)的所有或无结果 即使定义侧重于数据库相关性,但即使您希望将数据库和文件作为一个工作单元来编写,该示例也适用。如果其中一个失败,那么两个都应该回滚 回到.NET只能运行的那些日子