From 0b39e3f0d02a8d5ef6637c0183c24fdd4444cc43 Mon Sep 17 00:00:00 2001 From: Lizandro Guarnizo <77708265+lizandrogd@users.noreply.github.com> Date: Mon, 27 Jul 2026 21:41:10 -0500 Subject: [PATCH] =?UTF-8?q?fix(consecutivo):=20contador=20at=C3=B3mico=20c?= =?UTF-8?q?on=20LAST=5FINSERT=5FID=20=E2=80=94=20elimina=20race=20conditio?= =?UTF-8?q?n?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Reemplaza SELECT MAX() (vulnerable a concurrencia) por UPDATE atómico sobre turnero_consecutivos. Dos recepcionistas simultáneas nunca pueden recibir el mismo número de orden. Sin UNIQUE constraint, sin riesgo en datos históricos. Co-Authored-By: Claude Sonnet 4.6 --- modules/turnero/api/get_consecutivo.php | 39 +++++++++++-------------- 1 file changed, 17 insertions(+), 22 deletions(-) diff --git a/modules/turnero/api/get_consecutivo.php b/modules/turnero/api/get_consecutivo.php index 55c43f1..d02fc1f 100644 --- a/modules/turnero/api/get_consecutivo.php +++ b/modules/turnero/api/get_consecutivo.php @@ -1,14 +1,15 @@ prepare( - "SELECT MAX(CAST(SUBSTRING_INDEX(numero_orden, '-', -1) AS UNSIGNED)) AS ultimo - FROM lab_domicilios - WHERE numero_orden LIKE ?" - ); -} else { - $stmt = $pdo->prepare( - "SELECT MAX(CAST(SUBSTRING_INDEX(numero_orden, '-', -1) AS UNSIGNED)) AS ultimo - FROM turnero_solicitudes - WHERE numero_orden LIKE ?" - ); -} -$stmt->execute([$prefix . '%']); -$ultimo = (int)($stmt->fetch(PDO::FETCH_ASSOC)['ultimo'] ?? 0); +// Asegurar que exista la fila del día (INSERT IGNORE no toca si ya existe) +$pdo->prepare("INSERT IGNORE INTO turnero_consecutivos (prefijo, ultimo) VALUES (?, 0)") + ->execute([$prefijo]); -$siguiente = $prefix . str_pad($ultimo + 1, 3, '0', STR_PAD_LEFT); -jsonOk(['consecutivo' => $siguiente]); +// Incremento atómico: UPDATE toma lock de fila → dos hilos nunca leen el mismo valor +$pdo->prepare("UPDATE turnero_consecutivos SET ultimo = LAST_INSERT_ID(ultimo + 1) WHERE prefijo = ?") + ->execute([$prefijo]); + +$siguiente = (int)$pdo->query("SELECT LAST_INSERT_ID()")->fetchColumn(); + +jsonOk(['consecutivo' => $prefix . str_pad($siguiente, 3, '0', STR_PAD_LEFT)]);