Business
Jobs
  • About Us
  • Solutions
    • Job Postings
      Post your job and receive qualified candidates in 48h.
    • Candidate Assessments
      500+ technical and psychological tests, plus anti-fraud.
    • Headhunting
      Tailor-made executive search from start to finish.
    • Payroll + EOR
      Payroll dispersal and EOR across 15+ LATAM countries.
  • Pricing
  • Jobs

0

101
Views
¿Cómo evito que una transacción mySQL se ejecute simultáneamente en Node.js Express?

Realmente estoy luchando por lograr algo que en realidad considero bastante trivial y me está volviendo loco.
Solo quiero que la siguiente transacción de la base de datos MySQL se excluya mutuamente. Por lo tanto, una segunda llamada tendría que esperar hasta que finalice la primera llamada.
Ya probé el marco async-mutex de npm, envolviendo todo en promesas, la cláusula SELECT ... FOR UPDATE de MySQL, pero ninguno de estos conduce al resultado esperado.
El comportamiento actual es el siguiente: cuando 2 solicitudes HTTP ingresan simultáneamente y llaman a la siguiente función de modelo, ambas ingresan a la función canEntryBeInserted que obviamente conduce a resultados incorrectos. me gustaría tener

1 2 1 2

pero lo consigo

1 1 2 2 .

 exports.addEntry = function (entry_id, type) { return new Promise(function (resolve, reject) { console.log("1") beginTransactionP().then(function () { canEntryBeInserted(entry_id, type).then(function (canBeInserted) { if (canBeInserted) { addEntrySQL(entry_id, type).then(function(){ finishTransactionP().then(function() { console.log("2") resolve(); }) }) } else { finishTransactionP().then(function() { console.log("2") resolve(); }) } }) }) }) } addEntrySQL = function(entry_id, type){ return new Promise(function (resolve, reject) { sql.query("INSERT INTO entry (entry_id, typ, time) VALUES (?, ?, NOW());", [entry_id, type], function (err, rows, fields) { if (err) { console.log("error: ", err); reject(err); } else { console.log("Inserted successfully.") resolve(); } }); }) } canEntryBeInserted = function (entry_id, type) { return new Promise(function (resolve, reject) { sql.query("SELECT * FROM entry WHERE entry_id = ? AND typ = 1 UNION SELECT * FROM entry WHERE entry_id = ? ORDER BY entry_id DESC LIMIT 1;", [entry_id, entry_id], function (err0, rows0) { console.log(JSON.stringify(rows0), type) if (err0) { console.log("error: ", err0); reject(err0) } else if ((rows0.length == 1 && (rows0[0].typ == type || rows0[0].typ == 1)) || rows0.length == 2) { console.log("Error: Not a valid operation."); resolve(false) } else { resolve(true) } }) }) }
about 4 years ago · Juan Pablo Isaza
1 answers
Answer question

0

El siguiente código demuestra cómo una función asincrónica puede adquirir un bloqueo, lo que evita la ejecución simultánea hasta que se libera el bloqueo nuevamente.

 var locked; function lock(req, res, next) { if (locked) locked.on("release", next); else { locked = new EventEmitter(); next(); } } function unlock() { if (locked) { locked.emit("release"); locked = undefined; } } app.use(lock, function(req, res) { console.log("1"); setTimeout(function() { console.log("2"); res.end(); unlock(); }, 1000); });

Esto mantiene el bloqueo en el nivel de Javascript en el lock de variable global. Es posible que necesite algo más granulado fino.

También es posible un bloqueo de nivel de base de datos con select for update , pero si eso falla, la solicitud tendría que volver a intentarlo hasta que tenga éxito, porque la base de datos no emite un evento de release como el código anterior.

about 4 years ago · Juan Pablo Isaza Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Sales
Legal
Terms and conditions Privacy policy
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Show me some job opportunities
There's an error!