在for循环打字稿和nhibernate死锁中调用异步函数
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了在for循环打字稿和nhibernate死锁中调用异步函数相关的知识,希望对你有一定的参考价值。
我正在使用typescript在for循环中编写一个http post调用。
在后端调试方法时,我注意到他同时处理请求。
例如,假设服务器必须运行2个方法M1()
然后M2()
每个请求。对于n = 2的测试用例。服务器为请求1执行M1()
,为请求2执行M1()
,然后为请求2执行M2()
,最后为请求2执行M2()
。
然后在_session.commit()
之后在方法拦截中抛出异常。例外描述是:
NHibernate.StaleObjectStateException:'行已被另一个事务更新或删除(或未保存的值映射不正确):[Server.Model.Identity.ApplicationRole#3]'
码:
public calculate(index?: number): void {
for (var i = 0; i < this.policy.coverages.length; i++) {
this.callCalculate(i);
}
}
public callCalculate(i: number): void {
this.premiumCalculationParams = this.policy.createPremiumCalculationParams();
if (!this.premiums) {
this.premiums = new Array(this.policy.coverages.length);
}
this.offerService.calculatePremiums(this.policy, i).then((result: any) => {
this.premiums[i] = new Array<Premium>();
this.surpremiums = new Array<PremiumResult>();
if (result.data && result.data.premiumTable && result.data.premiumTable.premiumPayment && result.data.premiumTable.premiumPayment.premiums && result.data.premiumTable.premiumPayment.premiums.length > 0) {
_.each(result.data.premiumTable.premiumPayment.premiums, (premiumValue: any) => {
let premium: Premium = new Premium();
premium.setPremium(premiumValue);
this.premiums[i].push(premium);
this.policy.getCoverage(i).premiumPayment.premiums = angular.copy(this.premiums[i]);
});
if (result.data && result.data.results && result.data.results.length > 0) {
_.each(result.data.results, (premiumValuel: any) => {
let sp = new PremiumResult();
sp.setPremiumResult(premiumValuel);
sp.premiums = new Array<Premium>();
_.each(premiumValuel.premiums, (premiumValue: any) => {
let premium: Premium = new Premium();
premium.setPremium(premiumValue);
sp.premiums.push(premium);
});
this.surpremiums.push(sp);
});
}
console.log(this.surpremiums);
}
if (result.data && result.data.premiumTable && result.data.premiumTable.messageList && result.data.premiumTable.messageList.messages && result.data.premiumTable.messageList.messages.length > 0) {
_.each(result.data.premiumTable.messageList.messages, (message: any) => {
let messageType: any = MessageType[message.messageLevel.toString()];
this.messages.push(new Message(messageType, "premiums", message.messageContent, this.premiums[i]));
});
}
}, (err: any) => {
this.premiums[i] = null;
this.surpremiums = null;
if (err && err.data && err.data.modelState) {
for (var key in err.data.modelState) {
var model = err.data.modelState[key];
_.each(model, (state: string) => {
this.$log.debug(OfferControllerPrefix, "Calculation failed: " + state);
});
}
}
this.messages.push(new Message(MessageType.SVR_ERROR, "premiumCalculationParams", this.jsTranslations.getTranslation(Constants.DEFAULT_ERROR_NL), this.policy));
});
}
public calculatePremiums(policy: Policy, selectedCoverageIndex : number): any {
var uri = this.uriService.buildURI("Policy/Calculate");
var data = {
'policy': policy,
'selectedCoverageIndex': selectedCoverageIndex
};
return this.$http.post<any>(uri, data);
}
如何解决这个问题?
答案
要链接两个异步操作,请将值返回到.then
方法:
function M1(data) {
return $http.post(url1, data);
}
function M2(data) {
return $http.post(url2, data);
}
链接这两个函数是这样的:
function M1M2 () {
var promise = M1(data);
var promise2 = promise.then(function(data) {
var data2 = fn(data);
var m2Promise = M2(data2);
return m2Promise;
});
return promise2;
}
因为调用promise的.then
方法会返回一个新的派生promise,所以很容易创建一个promise链。
可以创建任何长度的链,并且由于可以使用另一个承诺(将进一步推迟其解析)来解决承诺,因此可以在链中的任何点暂停/推迟承诺的解析。这使得实现强大的API成为可能。
有关更多信息,请参阅AngularJS $q Service API Reference - chaining promises。
以上是关于在for循环打字稿和nhibernate死锁中调用异步函数的主要内容,如果未能解决你的问题,请参考以下文章