1

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

  1. 在调用 API 调用的外部系统上编辑对象。
  2. 编辑我们系统数据库上的对象。

    [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)
        {
    

如上面的代码所示,我不会执行 repository.save() 来更新我们系统上的对象,除非 API 返回“成功”。但目前我面临以下问题:-如果API返回“成功”但发生并发异常,那么API将更新外部系统上的对象,但不会更新我们系统上的对象?那么有没有办法处理这种情况呢?

4

1 回答 1

1

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

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

于 2013-08-07T15:39:42.737 回答