PHP, MySQL, concurrencia
Publicado por wolverine4277 (4 intervenciones) el 04/01/2008 19:40:47
La situación es la siguiente, tengo una tabla con un campo de tipo caracter que no puede contener valores duplicados salvo la cadena '00000' (por lo tanto no puedo utilizar un índice para la validación de campo único).
La tabla con los siguientes registros sería un escenario válido:
id campo
-------------
1 11201
2 31242
3 00000
4 14649
...
124 00000
125 23234
ahora, si quisiera insertar la dupla (126, 31242) no tendría que poder hacerlo.
Lo primero que se me ocurrió fue:
<?php
$id = mysql_pconnect(..., ..., ...);
if ($id) {
if (mysql_select_db(..., $id)) {
$valid_value = false;
if ($_POST['value'] != '00000') {
$valid_value = true;
} else {
$sql = "SELECT COUNT(*) AS total ";
$sql.= "FROM table ";
$sql.= "WHERE (field <> '00000') AND (field = '" . $_POST['value'] . "')";
$dataset = mysql_query($sql, $id);
if ($dataset) {
if ($registro = mysql_fetch_assoc($dataset)) {
if ($registro['total'] == 0) {
$sql = "INSERT INTO tabla(field) ";
$sql.= "VALUES ('" . $_POST['value']. "')";
$result = mysql_query($sql, $id);
if (!$result) {
// Error message
} else {
// Ok
}
} else {
// Error message
}
} else {
// Error message
}
} else {
// Error message
}
} else {
// Error message
}
} else {
// Error message
}
}
?>
pero si no me equivoco ante la concurrencia de usuarios para realizar inserciones en la tabla puede fallar. El código es solo de ejemplo, no está depurado ni mucho menos.
• Usuario 1 esta ejecutando la primera sentencia SQL con lo cual no encuentra el valor a insertar en la tablas y sigue
• Usuario 2 ejecuta la primera sentencia SQL con lo cual no encuentra el valor a insertar en la tablas y sigue
• Usuario 2 inserta el valor
• Usuario 1 inserta el valor
¿Cuál sería la mejor aproximación para lograr las inserciones evitando la duplicación de los valores del campo? ¿Debo utilizar transacciones?
BEGIN TRANSACTION
Ejecutar sentencia SQL 1
Ejecutar sentencia SQL 2
COMMIT or ROLLBAK transaction
Gracias
La tabla con los siguientes registros sería un escenario válido:
id campo
-------------
1 11201
2 31242
3 00000
4 14649
...
124 00000
125 23234
ahora, si quisiera insertar la dupla (126, 31242) no tendría que poder hacerlo.
Lo primero que se me ocurrió fue:
<?php
$id = mysql_pconnect(..., ..., ...);
if ($id) {
if (mysql_select_db(..., $id)) {
$valid_value = false;
if ($_POST['value'] != '00000') {
$valid_value = true;
} else {
$sql = "SELECT COUNT(*) AS total ";
$sql.= "FROM table ";
$sql.= "WHERE (field <> '00000') AND (field = '" . $_POST['value'] . "')";
$dataset = mysql_query($sql, $id);
if ($dataset) {
if ($registro = mysql_fetch_assoc($dataset)) {
if ($registro['total'] == 0) {
$sql = "INSERT INTO tabla(field) ";
$sql.= "VALUES ('" . $_POST['value']. "')";
$result = mysql_query($sql, $id);
if (!$result) {
// Error message
} else {
// Ok
}
} else {
// Error message
}
} else {
// Error message
}
} else {
// Error message
}
} else {
// Error message
}
} else {
// Error message
}
}
?>
pero si no me equivoco ante la concurrencia de usuarios para realizar inserciones en la tabla puede fallar. El código es solo de ejemplo, no está depurado ni mucho menos.
• Usuario 1 esta ejecutando la primera sentencia SQL con lo cual no encuentra el valor a insertar en la tablas y sigue
• Usuario 2 ejecuta la primera sentencia SQL con lo cual no encuentra el valor a insertar en la tablas y sigue
• Usuario 2 inserta el valor
• Usuario 1 inserta el valor
¿Cuál sería la mejor aproximación para lograr las inserciones evitando la duplicación de los valores del campo? ¿Debo utilizar transacciones?
BEGIN TRANSACTION
Ejecutar sentencia SQL 1
Ejecutar sentencia SQL 2
COMMIT or ROLLBAK transaction
Gracias
Valora esta pregunta


0