如何在node.js,mssql和msnodesqlv8中正确执行循环查询

我试图做我以前在c#和asp.net webforms中所做的事情,并在事务中执行一些插入存储过程,其中一些是循环的。 我现在试图通过node.js与mssql包在angular度应用程序中这样做。 我到目前为止如下。

//Insert Change Record router.post('/insertChange', (req, res) => { const transaction = new sql.Transaction(conn); transaction.begin(err => { let rolledBack = false; transaction.on('rollback', aborted => { rolledBack = true; }) const request = new sql.Request(transaction); request.input('ChangeTitle', req.body.changeTitle); request.input('TypeId', req.body.typeId); request.input('DateSubmitted', req.body.dateSubmitted); request.input('TargetDate', req.body.targetProductionDate); request.input('ChangeSponsor', req.body.changeSponsor); request.input('UATDate', req.body.dateReadyUAT); request.input('ChangeSponsorEmail', req.body.changeSponsorEmail); request.input('ClarityId', req.body.clarityId); request.input('ChangeDescription', req.body.changeDescription); request.input('ComponentName', req.body.componentName); request.input('ComponentDescription', req.body.componentDescription); request.input('ReasonForChange', req.body.reasonForChange); request.input('ComponentREplacing', req.body.componentReplacing); request.input('DependentChange', req.body.dependentChange); request.input('InstallOption', req.body.installOption); request.input('RebootRequired', req.body.rebootRequired); request.input('UserIntervention', req.body.userIntervention); request.input('Activation', req.body.activation); request.input('ContingencyPlan', req.body.contingencyPlan); request.input('AdditionalInformation', req.body.additionalInformation); request.input('PerformanceImpact', req.body.applicationPerformance); request.input('IsPCoERequired', req.body.pcoeTesting); request.input('IsCanadianRetailBranch', req.body.pbsTesting); request.input('BusinessAppImpact', req.body.businessApplication); request.input('NetworkImpact', req.body.networkPerformance); request.input('NewInfrastructure', req.body.newInfrastructure); request.input('LogonTime', req.body.logonTime); request.input('AdditionalTechnicalInformation', req.body.additionalAssessmentInfo); request.input('IsProdIssue', req.body.isProdIssue); request.input('ProdIssue', req.body.productionIssue); request.input('ProdIncidentNum', req.body.incidentNumbers); request.input('IsMajorChange', req.body.isMajorChange); request.input('HasRequiredTesting', req.body.hasRequiredTesting); request.input('HasPackageSubmit', req.body.hasPackageSubmit); request.input('SignOffETA', req.body.signoffETA); request.input('SpecificTesting', req.body.specificTesting); request.input('SpecificPilot', req.body.specificPilot); request.input('PilotInfo', req.body.pilotTransits); request.input('UserChanges', req.body.userDifferences); request.input('ServiceDeskProcedure', req.body.procedureSupport); request.input('SupportCallFlowId', req.body.supportCallFlow); request.input('OverallChangeStatus', 1); let changeId = request.output('changeId', sql.Int); request.execute('dbo.InsertChange').then(function (result) { console.dir(result); }).catch(function (err) { console.dir(err); }); async.each( req.body.changeType ,function iterator(item, next) { const requestCT = new sql.Request(transaction); requestCT.input('ChangeId', changeId); requestCT.input('TypeOfChangeId', item.typeOfChangeId); requestCT.input('Description', item.description); requestCT.execute('dbo.InsertTypeOfChange').then(function (result) { console.dir(result); next(); }).catch(function (err) { console.dir(err); }); }) async.each( req.body.serviceImpacted ,function iterator(item, next) { const requestSI = new sql.Request(transaction); requestSI.input('ChangeId', changeId); requestSI.input('ServicesImpactedId', item.serviceImpactedId); requestSI.execute('dbo.InsertImpactedService').then(function (result) { console.dir(result); next(); }).catch(function (err) { console.dir(err); }); }) async.each( req.body.businessImpacted ,function iterator(item, next) { const requestBI = new sql.Request(transaction); requestBI.input('ChangeId', changeId); requestBI.input('BusinessImpactedId', item.businessImpactedId); requestBI.execute('dbo.InsertImpactedBusiness').then(function (result) { console.dir(result); next(); }).catch(function (err) { console.dir(err); }); }) async.each( req.body.criticalApp ,function iterator(item, next) { const requestCA = new sql.Request(transaction); requestCA.input('ChangeId', changeId); requestCA.input('CriticalBankingId', item.criticalId); requestCA.input('Description', item.description); requestCA.execute('dbo.InsertCriticalBankingApp').then(function (result) { console.dir(result); next(); }).catch(function (err) { console.dir(err); }); }) async.each( req.body.testStages ,function iterator(item, next) { const requestTS = new sql.Request(transaction); requestTS.input('ChangeId', changeId); requestTS.input('TestStageId', item.testStageId); requestTS.input('TestDate', item.testDate); requestTS.input('Description', item.description); requestTS.execute('dbo.InsertChangeTest').then(function (result) { console.dir(result); next(); }).catch(function (err) { console.dir(err); }); }) if (err) { if (!rolledBack) { transaction.rollback(err => { console.dir(err); // ... error checks }) } } else { transaction.commit(err => { console.dir(err); // ... error checks }) } }) }); 

在处理与存储过程交易的任何地方,实际上并不存在大量的材料,甚至对于像这样的大型交易来说更是如此。 但是我得到的错误是在我的terminal日志中多次。

 { TransactionError: Can't acquire connection for the request. There is another request in progress. at Transaction.acquire (C:\Users\Redirection\meecd26\Documents\GitRepo\td-angular-starter\node_modules\mssql\lib\base.js:740:30) at Immediate._query.err [as _onImmediate] (C:\Users\Redirection\meecd26\Documents\GitRepo\td-angular-starter\node_modules\mssql\lib\msnodesqlv8.js:417:19) at runCallback (timers.js:781:20) at tryOnImmediate (timers.js:743:5) at processImmediate [as _immediateCallback] (timers.js:714:5) code: 'EREQINPROG', name: 'TransactionError' } 

这当然表明我正在进行不正当的交易​​。

有人能够帮助指导我如何改善和解决这个问题吗?

编辑:对我的代码进行了更改,以反映我在这里find的内容,以及对第一次插入的一些更改。 虽然我的第一个插入工作,我仍然得到上面的重复错误,所以现在我知道我的问题是我如何在循环内实施插入。 有没有一种方法可以closures每个插件的连接? 这是我应该尝试采取的方法吗?

我最终得到了它的工作,虽然我对于一切工作的理解,虽然承认没有多less改善,但我至less可以张贴我希望其他人希望find的帮助。

 router.post('/insertChange', (req, res) => { console.log("Beginning of POST, before initializing transaction"); let changeId; let mainInsert = false; beginTransaction(function (err, rollback, transaction) { if (err) { // return cb(err); } let request = new sql.Request(transaction); // request.verbose = true; request.input('ChangeTitle', req.body.ChangeTitle); request.input('TypeId', req.body.TypeId); request.input('DateSubmitted', req.body.DateSubmitted); request.input('TargetDate', req.body.TargetDate); request.input('ChangeSponsor', req.body.ChangeSponsor); request.input('UATDate', req.body.UATDate); request.input('ChangeSponsorEmail', req.body.ChangeSponsorEmail); request.input('ClarityId', req.body.ClarityId); request.input('ChangeDescription', req.body.ChangeDescription); request.input('ComponentName', req.body.ComponentName); request.input('ComponentDescription', req.body.ComponentDescription); request.input('ReasonForChange', req.body.ReasonForChange); request.input('ComponentReplacing', req.body.ComponentReplacing); request.input('DependentChange', req.body.DependentChange); request.input('InstallOption', req.body.InstallOption); request.input('RebootRequired', req.body.RebootRequired); request.input('UserIntervention', req.body.UserIntervention); request.input('Activation', req.body.Activation); request.input('ContingencyPlan', req.body.ContingencyPlan); request.input('AdditionalInformation', req.body.AdditionalInformation); request.input('PerformanceImpact', req.body.PerformanceImpact); request.input('IsPCoERequired', req.body.IsPCoERequired); request.input('IsCanadianRetailBranch', req.body.IsCanadianRetailBranch); request.input('BusinessAppImpact', req.body.BusinessAppImpact); request.input('NetworkImpact', req.body.NetworkImpact); request.input('NewInfrastructure', req.body.NewInfrastructure); request.input('LogonTime', req.body.LogonTime); request.input('AdditionalTechnicalInformation', req.body.AdditionalTechnicalInformation); request.input('IsProdIssue', req.body.IsProdIssue); request.input('ProdIssue', req.body.ProdIssue); request.input('ProdIncidentNum', req.body.ProdIncidentNum); request.input('IsMajorChange', req.body.IsMajorChange); request.input('HasRequiredTesting', req.body.HasRequiredTesting); request.input('HasPackageSubmit', req.body.HasPackageSubmit); request.input('SignOffETA', req.body.SignOffETA); request.input('SpecificTesting', req.body.SpecificTesting); request.input('SpecificPilot', req.body.SpecificPilot); request.input('PilotInfo', req.body.PilotInfo); request.input('UserChanges', req.body.UserChanges); request.input('ServiceDeskProcedure', req.body.ServiceDeskProcedure); request.input('SupportCallFlowId', req.body.SupportCallFlowId); request.input('OverallChangeStatus', 1); request.output('changeId', sql.Int); request.execute('dbo.InsertChange', function (err, callback) { if (err) { console.dir(err); rollback(err); res.status(400).send("Failed to submit change form."); } else { mainInsert = true; } if (callback) { changeId = +callback.returnValue; } if (mainInsert) { async.each( req.body.changeType, function iterator(item, next) { request = new sql.Request(transaction); request.input('ChangeId', changeId); request.input('TypeOfChangeId', item.typeOfChangeId); request.input('Description', item.description); request.execute('dbo.InsertTypeOfChange', function (err, callback) { if (err) return next(err); console.dir(callback); next(); }) }, function fin(err) { if (err) { rollback(err); return; //done } }) async.each( req.body.serviceImpacted, function iterator(item, next) { request = new sql.Request(transaction); request.input('ChangeId', changeId); request.input('ServicesImpactedId', item.serviceImpactedId); request.execute('dbo.InsertImpactedService', function (err, callback) { if (err) return next(err); console.dir(callback); next(); }) }, function fin(err) { if (err) { rollback(err); return; //done } }) async.each( req.body.businessImpacted, function iterator(item, next) { request = new sql.Request(transaction); request.input('ChangeId', changeId); request.input('BusinessImpactedId', item.businessImpactedId); request.execute('dbo.InsertImpactedBusiness', function (err, callback) { if (err) return next(err); console.dir(callback); next(); }) }, function fin(err) { if (err) { rollback(err); return; //done } }) async.each( req.body.criticalApp, function iterator(item, next) { request = new sql.Request(transaction); request.input('ChangeId', changeId); request.input('CriticalBankingId', item.criticalId); request.input('Description', item.description); request.execute('dbo.InsertCriticalBankingApp', function (err, callback) { if (err) return next(err); console.dir(callback); next(); }) }, function fin(err) { if (err) { rollback(err); return; //done } }) async.each( req.body.testStages, function iterator(item, next) { request = new sql.Request(transaction); request.input('ChangeId', changeId); request.input('TestStageId', item.testStageId); request.input('TestDate', item.testDate); request.input('Description', item.description); request.execute('dbo.InsertChangeTest', function (err, callback) { if (err) return next(err); console.dir(callback); next(); }) }, function fin(err) { if (err) { rollback(err); return; //done } else { transaction.commit(function (err) { if (err) { console.error('Transaction commit error: ', err); res.status(400).send("Failed to submit change form."); } else { console.error('Transaction commit success'); res.send({ "Response": "Success", "Message": "Change form successfully submitted." }); } }); } }) } }); }) });