Empresas
Empregos
  • Sobre nós
  • Soluções
    • Publicação de vagas
      Publique sua vaga e receba candidatos qualificados em 48h.
    • Avaliações de candidatos
      Mais de 500 testes técnicos e psicológicos, mais anti-fraude.
    • Headhunting
      Busca executiva personalizada do início ao fim.
    • Folha de Pagamento + EOR
      Dispersão de folha e EOR em mais de 15 países da LATAM.
  • Preços
  • Empregos

0

110
Visualizações
¿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 Respostas
Responde à pergunta

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 Relatório
Responde à pergunta
Encontrar trabalhos remotos

Descubra a nova forma de encontrar um emprego!

melhores empregos
Principais categorias de trabalho
Empresas
Postar vaga Preços Comercial
Jurídico
Termos e Condições Política de privacidade
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomende algumas ofertas para mim
Preciso de ajuda