Asp.net mvc 使用外部API调用处理并发异常

Asp.net mvc 使用外部API调用处理并发异常,asp.net-mvc,entity-framework,Asp.net Mvc,Entity Framework,我有以下编辑后操作方法,主要执行两个更新操作:- 使用API调用在外部系统上编辑对象 编辑系统数据库上的对象 [HttpPost] public ActionResult Create(RackJoin rj, FormCollection formValues) {string controllername = RouteData.Values["controller"].ToString(); if (ModelState.IsValid) { var message = "";

我有以下编辑后操作方法,主要执行两个更新操作:-

  • 使用API调用在外部系统上编辑对象
  • 编辑系统数据库上的对象

    [HttpPost]
    public ActionResult Create(RackJoin rj, FormCollection formValues)
    {string controllername = RouteData.Values["controller"].ToString();
    if (ModelState.IsValid)
    {  var message = "";
                    var status = "";
                    long assetid = new long();
                    XmlDocument doc = new XmlDocument();
                    using (var client = new WebClient())
                    {
                        var query = HttpUtility.ParseQueryString(string.Empty);
                        foreach (string key in formValues)
                        {
                            query[key] = this.Request.Form[key];
                        }
    
    query["username"] =  System.Web.Configuration.WebConfigurationManager.AppSettings["ApiUserName"];
    query["password"] =  System.Web.Configuration.WebConfigurationManager.AppSettings["ApiPassword"];
    string apiurl = System.Web.Configuration.WebConfigurationManager.AppSettings["ApiURL"];
    var url = new UriBuilder(apiurl);
    url.Query = query.ToString();
    try
    {
    string xml = client.DownloadString(url.ToString());
    
                            doc.LoadXml(xml);
     status = doc.SelectSingleNode("/operation/operationstatus").InnerText;
                            message = doc.SelectSingleNode("/operation/message").InnerText;
    }
                        catch (WebException ex)
                        {
                            ModelState.AddModelError(string.Empty, "Error occurred:" + ex.InnerException);
                        }
                    }
                     if (status.ToUpper() == "SUCCESS")
                {
                    repository.InsertOrUpdateRack(rj.Rack, User.Identity.Name, rj.Resource.RESOURCEID);
                    repository.Save();
                    return RedirectToAction("Index");
                }
                else
                {
                    ModelState.AddModelError(string.Empty, message.ToString());
    
                }
            }
        }
        catch (DbUpdateConcurrencyException ex)
        {
    
  • 如上面代码所示,除非API返回“success”,否则我不会使用repository.save()更新系统上的对象。 但目前我面临以下问题:- 如果API返回“成功”,但发生并发异常,则API将更新外部系统上的对象,但不会更新我们系统上的对象?
    那么有没有办法处理这种情况呢?

    解决这种情况没有简单的办法。处理它的一种方法是要求外部API的设计者公开一个方法,该方法允许提交在前一次调用中完成的事务。基本上,您的第一次调用将对外部系统进行修改,但带有一些布尔标志,指示这些更改仍处于挂起状态。然后更新系统,如果成功,则调用外部API将数据从挂起标记为有效


    如果您无法控制外部API,并且它使第一次调用的数据更改不可逆,那么恐怕您没有太多选择余地了。在调用API之前,您可能还记得要在外部系统上修改的对象的状态,如果系统出现异常,请使用以前的值调用API以恢复到以前的状态。

    解决这种情况没有简单的方法。处理它的一种方法是要求外部API的设计者公开一个方法,该方法允许提交在前一次调用中完成的事务。基本上,您的第一次调用将对外部系统进行修改,但带有一些布尔标志,指示这些更改仍处于挂起状态。然后更新系统,如果成功,则调用外部API将数据从挂起标记为有效


    如果您无法控制外部API,并且它使第一次调用的数据更改不可逆,那么恐怕您没有太多选择余地了。在调用API之前,您可能还记得要在外部系统上修改的对象的状态,如果系统出现异常,请使用以前的值调用API以恢复到以前的状态。

    谢谢您的回复,不幸地要求修改API是不可能的,因为我们是从外部公司购买的。感谢回复,不幸地要求修改API是不可能的,因为我们是从外部公司购买的。