Foros del Web » Programación para mayores de 30 ;) » Bases de Datos General » Mysql »

Impedir que dos procesos accedan al mismo tiempo a una tabla

Estas en el tema de Impedir que dos procesos accedan al mismo tiempo a una tabla en el foro de Mysql en Foros del Web. Hola. En un proyecto que estoy realizando necesito generar una cadena del tipo de la id de los vídeos de YouTube (v15Kj001S4t8xRP) que será almacenada ...
  #1 (permalink)  
Antiguo 19/05/2008, 17:30
 
Fecha de Ingreso: noviembre-2007
Ubicación: Córdoba
Mensajes: 70
Antigüedad: 16 años, 5 meses
Puntos: 1
Pregunta Impedir que dos procesos accedan al mismo tiempo a una tabla

Hola.

En un proyecto que estoy realizando necesito generar una cadena del tipo de la id de los vídeos de YouTube (v15Kj001S4t8xRP) que será almacenada en una tabla como id de un archivo. Dado que va a ser la id que identifique a ese archivo en la tabla, no puede existir ningún duplicado. La forma simple de hacerlo es generar una id nueva por cada archivo nuevo, ver si existe ya una en la base de datos, si existe crear una nueva y repetir la comprobación (así hasta que no exista) y si no existe pues esa que se ha generado es válida. Al principio lo normal será que no existan muchos registros, por lo que la posibilidad de hallar repetidas será inferior. Pero con el paso del tiempo, y sobre todo si se prevee que se insertarán muchos archivos, la probabilidad de hallar coincidencias será cada vez mayor, lo que supondría perdida de tiempo hasta generar una clave que no exista.

Para evitar eso he pensado en tener un proceso aparte que vaya generando claves que no existan para tenerlas a punto cuando deba usarse alguna para un nuevo archivo. Esas claves irían almacenadas en una tabla de MySQL. Pero el problema viene cuando yo le digo a MySQL: "oye, dame la siguiente clave disponible que tengas en la lista". Desde que yo realizo la consulta SELECT para obtener la clave hasta que vuelvo a realizar la consulta DELETE para borrar esa clave por que ya ha sido usada, existe un intervalo de tiempo en el que otra petición podría decirle a MySQL que le de una clave disponible y MYSQL, como sigue teniendo ese registro ahí, pues darle la misma clave: y ya la tenemos liada.

¿De que forma podría yo hacer esa consulta? ¿Transacciones? ¿Bloqueo de tabla? No tengo ni idea de esas cosas. Gracias y perdón por el tocho.

Saludos.
__________________
http://www.javierav.com
  #2 (permalink)  
Antiguo 20/05/2008, 02:09
Colaborador
 
Fecha de Ingreso: marzo-2008
Ubicación: Sabadell
Mensajes: 4.897
Antigüedad: 16 años, 1 mes
Puntos: 574
Respuesta: Impedir que dos procesos accedan al mismo tiempo a una tabla

El problema que planteas es de manejo de transacciones, pero no es aplicable a las claves principales PK, en el caso de la PK es el motor que se preocupa del promblema de manera transparente para el programador.

Tienes dos opciones que yo conozca:

Definir el id como autoincremental asegura una clave unica sin comprobaciones previas, la clave sera un numero.

Tambien existe el tipo de datos GUID (Globally Unique Identifier) que genera una clave unica a nivel "mundial" puesto que depende de los identificadores unicos del hard que la esta generando (no se como se implementa en MySQL). Este ocupa bastante mas espacio en disco pero su aspecto seria mas parecido al ejemplo que propones.


En el caso del autoinc lo que no puedes hacer es mostrar el id que tocaria antes de insertar el registro pero si despues de insertarlo, puesto que en ese momento ya ha sido asiognado y seguro que es ese.


Quim
  #3 (permalink)  
Antiguo 20/05/2008, 17:10
 
Fecha de Ingreso: noviembre-2007
Ubicación: Córdoba
Mensajes: 70
Antigüedad: 16 años, 5 meses
Puntos: 1
Respuesta: Impedir que dos procesos accedan al mismo tiempo a una tabla

Hola.

Gracias por tu respuesta. El caso de GUID ya lo estuve viendo para otro proyecto de programación, y efectivamente sirve para identificar un ordenador de la misma forma que una MAC identifica de forma única en el mundo a una tarjeta de red. Pero en este caso no me sirve, por que sólo tendría un GUID que sería el correspondiente al servidor web.

Veo que no se va a poder hacer mi planteamiento de esa forma. De todas formas aprovecho este hilo para otra pregunta relacionada:

¿Se puede dar el caso de que dos consultas se ejecuten al mismo tiempo? ¿O siempre habrá una que se ejecute en primer lugar? Lo digo por que si yo le doy al campo que contiene la ID un indice UNICO (que entiendo es que no se puede repetir su valor), en el caso de que dos consultas intentasen añadir un registro con la misma ID, la primera se almacenaría y la segunda daría error por existir ya una clave igual.. ¿Es eso así? Gracias de nuevo.

Saludos.
__________________
http://www.javierav.com
  #4 (permalink)  
Antiguo 20/05/2008, 21:37
Avatar de gnzsoloyo
Moderador criollo
 
Fecha de Ingreso: noviembre-2007
Ubicación: Actualmente en Buenos Aires (el enemigo ancestral)
Mensajes: 23.324
Antigüedad: 16 años, 5 meses
Puntos: 2658
Respuesta: Impedir que dos procesos accedan al mismo tiempo a una tabla

Las consultas que se ejecutan en forma simultánea son precisamente el corazón del problema de la administración de base de datos distribuidas y en red. Es justamente allí donde nace la necesidad de las transacciones, que permiten el desarrollo de consultas multithread.
No es un tema que se pueda responder en un post. Se trata de algo que implica MUCHO análisis, MUCHO diseño, MUCHA programación y otros muchos más. Hay tratados completos sobre el tema.
Para decirlo brevemente, la existencia de transacciones concurrentes es algo que se debe considerar siempre que se desarrolla una base de datos que se accederá por más de un usuario simultáneamente. Para ello existen sentencias y comandos, tanto a nivel de la base de datos, como al nivel de la aplicación, que permite que los threads de las consultas se ejecuten en una secuencia que no genere inconsistencias y problemas de integridad.
A nivel de las transacciones, debe diseñarse cada consulta y cada procedimiento para que ciertos pasos se consideren atómicos (indivisibles) y si se aborta una sola fase del proceso, se aborte totalmente la transacción. Este tipo de acciones está definida por el concepto de ACID (Atomicity, Consistency, Isolation and Durability) y se implementa de formas bastante complejas.
Un ejemplo del uso de las transacciones concurrentes lo tienes frente a tí casi a diario: Los cajeros automáticos de los bancos. Funcionan bajo ese principio. Si quieres acceder, por ejemplo, en dos cajeros con dos tarjetas a la misma cuenta, puedes hacerlo, pero retirar dinero, solamente podrá hacerlo uno a la vez de la misma cuenta, y si después de ver el saldo de la cuenta, quisieras retirar todo el monto que te indicó de saldo, pero el otro cajero retira una parte, entonces tu no podrás retirar ese monto mostrado, porque entre que tu consultaste el saldo y que pediste el retiro, el otro cajero debitó x dinero de la misma cuenta, y por tanto el saldo es insuficiente.
Todo eso se controla con diferentes niveles de bloqueo. En algunas ocasiones se bloquea la lectura pero no la escritura (miras el saldo, pero no retiras aún), en otras se bloquea todo (consolidación de la cuenta), en otras la escritura, pero no la lectura (consultas pero no retiras).
¿Se entiende?

Este tipo de diseño puede implicar:
- Bloqueos a nivel de base.
- Bloqueos a nivel de tablas.
- Bloqueos a nivel de registro
- bloqueos a nivel de campo.
También puede implicar diseñar un conjunto de permisos aplicables a usuarios categorizados, crear roles de usuarios y de grupos, etc. Por caso, cuando en una empresa se registra un usuario, según el área de trabajo se le asigna un rol que contiene permisos predefinidos. Esto se hace para evitar tener que darle permisos manualmente, con lo que pueden cometerse errores.
En las .Net pueden controlarse directamente en la aplicación. En otros lenguajes es posible que se tenga que realizar mediante procedimientos almacenados.
Acá vas a encontrar más sobre el tema: Transacciones y operaciones atómicas
__________________
¿A quién le enseñan sus aciertos?, si yo aprendo de mis errores constantemente...
"El problema es la interfase silla-teclado." (Gillermo Luque)
  #5 (permalink)  
Antiguo 21/05/2008, 03:59
Colaborador
 
Fecha de Ingreso: marzo-2008
Ubicación: Sabadell
Mensajes: 4.897
Antigüedad: 16 años, 1 mes
Puntos: 574
Respuesta: Impedir que dos procesos accedan al mismo tiempo a una tabla

En entorno Microsoft existe un tipo de datos GUID que permite generar id unicos para los registros de una tabla creo que los construye con una función com la MAC de la maquina y el reloj . A eso me referia, no se si tambien existe en otros entornos....

Quim
Atención: Estás leyendo un tema que no tiene actividad desde hace más de 6 MESES, te recomendamos abrir un Nuevo tema en lugar de responder al actual.
Respuesta

SíEste tema le ha gustado a 1 personas (incluyéndote)




La zona horaria es GMT -6. Ahora son las 10:33.