我有以下POST编辑操作方法,主要执行两个Update操作: -
编辑系统数据库中的对象。
[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将更新外部系统上的对象,但该对象不会在我们的系统上更新? 那么有办法处理这种情况吗?
答案 0 :(得分:1)
解决这种情况并不容易。处理它的一种方法是要求外部API的设计者公开一种允许在先前调用中完成事务的方法。基本上你的第一个调用将修改外部系统,但有一些布尔标志表明这些更改仍然未决。然后更新系统,如果成功,您可以调用外部API将数据从挂起标记为有效。
如果您无法控制外部API并且它使第一次调用中的数据更改不可逆转,那么我担心您没有太多选择。在调用API之前,您可能记住在外部系统上修改的对象的状态,如果系统出现异常,将恢复到之前的状态使用以前的值调用API。