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

bloqueo de registros para manejar concurrencia

Estas en el tema de bloqueo de registros para manejar concurrencia en el foro de Mysql en Foros del Web. Hola amigos, el dia de hoy acudo a ustedes porque tengo un gran reto, y es el manejo de los registros de una tabla, resulta ...
  #1 (permalink)  
Antiguo 04/12/2013, 07:22
 
Fecha de Ingreso: diciembre-2012
Mensajes: 249
Antigüedad: 11 años, 4 meses
Puntos: 2
bloqueo de registros para manejar concurrencia

Hola amigos, el dia de hoy acudo a ustedes porque tengo un gran reto, y es el manejo de los registros de una tabla,
resulta que tengo un paginador que me trae los clientes uno por uno, es decir se realiza una consulta de este tipo

Código MySQL:
Ver original
  1. SELECT * FROM clientes  LIMIT $siguiente,$mostrar

en donde en $siguiente le paso el contacto q sigue y la cantidad a $mostrar q en este caso seria 1, es decir, el paginador me esta mostrando cliente por cliente..
resulta que cuando yo muestro un cliente necesito que nadie mas pueda acceder a ese cliente, como si quedara bloqueado o invisible mientras otro usuario los esta viendo, esto con el fin de que si lo va a editar o borrar, no se vayan a cruzar con otro usuario, y asi manejar la concurrencia.

Por ahora he estado leyendo y encontre que se pueden bloquear registros con la sentencia
Código Javascript:
Ver original
  1. SELECT * FROM clientes  LIMIT $siguiente,$mostrar LOCK IN SHARE MODE
al final de select, pero no me ha funcionado, no se si este bien y si este por buen camino.. si alguien me puede ayudar con mi consulta, les agradeceria mucho
  #2 (permalink)  
Antiguo 04/12/2013, 07:30
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: bloqueo de registros para manejar concurrencia

Primera pregunta esencial: ¿Qué tipo de tablas usas? ¿InnoDB o MyISAM?
__________________
¿A quién le enseñan sus aciertos?, si yo aprendo de mis errores constantemente...
"El problema es la interfase silla-teclado." (Gillermo Luque)
  #3 (permalink)  
Antiguo 04/12/2013, 07:51
 
Fecha de Ingreso: diciembre-2012
Mensajes: 249
Antigüedad: 11 años, 4 meses
Puntos: 2
Respuesta: bloqueo de registros para manejar concurrencia

mysql InnoDB
  #4 (permalink)  
Antiguo 04/12/2013, 07:56
 
Fecha de Ingreso: diciembre-2012
Mensajes: 249
Antigüedad: 11 años, 4 meses
Puntos: 2
Respuesta: bloqueo de registros para manejar concurrencia

vale aclarar q habia hecho la variable temporal de 1 o 0, en el caso de 1 cuando se le hiciera el select a ese cliente y 0 cuando lo desocupara y pasara al siguiente cliente el cual tomaria el valor de 1, el problema es q por la latencia de la base y eso, aveces cuando 2 usuarios le daban click al mismo tiempo para mostrar los clientes, les salia el mismo cliente, y eso es lo q debo evitar. Gracias
  #5 (permalink)  
Antiguo 04/12/2013, 08:16
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: bloqueo de registros para manejar concurrencia

Cita:
vale aclarar q habia hecho la variable temporal de 1 o 0, en el caso de 1 cuando se le hiciera el select a ese cliente y 0 cuando lo desocupara y pasara al siguiente cliente el cual tomaria el valor de 1
Una variable temporal... ¿En qué contexto? ¿La aplicación o en la conexión de MySQL?
Por las dudas, te recuero que las variables de usuario de MySQL del tipo "@nombrevariable", existen para cada sesión de conexión, y son invisibles para otra conexión. Es decir, si usaste ese tipo, puede declararla y usar el mismo nombre en diferentes conexiones a la base, incluso con el mismo usuario, y serían todas variables distintas, invisibles de una conexión a otra.

Otro detalle es que la lectura en el caso de concurrencia, cuando usas LOCK IN SHARE MODE, implica que la conexión no se cierra en ningún momento. Si se cerrase la conexión (por la razón que fuese), el bloqueo se cae.
__________________
¿A quién le enseñan sus aciertos?, si yo aprendo de mis errores constantemente...
"El problema es la interfase silla-teclado." (Gillermo Luque)

Última edición por gnzsoloyo; 04/12/2013 a las 08:26
  #6 (permalink)  
Antiguo 04/12/2013, 08:31
 
Fecha de Ingreso: diciembre-2012
Mensajes: 249
Antigüedad: 11 años, 4 meses
Puntos: 2
Respuesta: bloqueo de registros para manejar concurrencia

aaah bueno pues yo la hice en el contexto de php, ese debe ser mi error?, todo los hacia desde la aplicacion.. y hasta ahora me familiarizo con las variables de usuario de mysql, bueno pues entonces que me recomendarias, para hacer esto definitivo, usar las variables de sesion de mysql? tienes algun ejemplito? pues es q no se muy bien como se puedan declararar y renombrar? eso se hace desde donde? y otra cosa, pues se me acabo de venir a la mente, pues habia pensado en un trigger pero como no existe el trigger de before select ya me he liado jeje graciass
  #7 (permalink)  
Antiguo 04/12/2013, 08:44
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: bloqueo de registros para manejar concurrencia

Me parece que no has terminado de entender el problema.
Vamos por partes:
1) Lo que hagas en PHP o cualquier lenguaje, a la base de datos ni le importa, ni se entera, en tanto no le estés mandando sentencias o comandos directos. MySQL (y ningún DBMS) "habla" con la aplicación, es un servicio que está a la escucha de un puerto, donde recibe sentencias y devuelve resultados. Pero no interactúa directamente con las aplicaciones.
2) Las variables de PHP son visibles únicamente para la sesión del usuario de la aplicación, y son diferentes para cada uno de ellos que esté usando la aplciación.
3) Las variables de usuario de MySQL son invisibles para otro usuario, y sólo existen mientras la conexión del usuario que las utilizó siga activa. Mueren con la conexión si esta se cierra, sea intencionalmente o accidentalmente (por timeout, por ejemplo).
4) Los bloqueos compartidos como que quieres usar son el modo adecuado, pero debes tener mucho cuidado en que la conexión sobre la que enviaste ese bloqueo no se cierre ni se caiga, o de lo contrario el bloqueo se libera.

Si el sistema que tienes tiene demasiada latencia, o inestabilidad de parte de los usuarios, es probable que haya que manejar el tema de un modo algo más rústico, pero más eficiente para el caso.
__________________
¿A quién le enseñan sus aciertos?, si yo aprendo de mis errores constantemente...
"El problema es la interfase silla-teclado." (Gillermo Luque)
  #8 (permalink)  
Antiguo 04/12/2013, 11:37
 
Fecha de Ingreso: diciembre-2012
Mensajes: 249
Antigüedad: 11 años, 4 meses
Puntos: 2
Respuesta: bloqueo de registros para manejar concurrencia

aaam ya veo, gnzsoloyo muchas gracias por la paciencia y las explicaciones, creo que ya estoy entendiendo un poco mas , pero me gustaria saber si voy bien:
1. digamos que yo le hago un select a un registro del cliente 1, a la vez le asigno ese id a mi variable de usuario mysql (SET @var1 = idCliente;), esto lo podria hacerlo mediante un transact, pienso yo, con el fin de que me ejecute toda la sentencia, voy bien?

2. Cuando el segundo usuario del sistema vaya a seleccionar un cliente, lo primero que se debe hacer es una consultar si ese registro ya esta siendo leido, y no se q sigue ya me volvi a liar....

que pena gnzsoloyo pero imaginate que el sistema lo esta usando un callcenter, en donde muchas personas estan consultando a la vez la misma tabla, y a cada una le tiene q salir un registro diferente, no puede salirle el mismo registro a 2 personas diferentes.. creo q me estoy enloqueciendo jejejej pero no entiendo muy bien como puedo solucionar mi problema

Última edición por summerblack; 04/12/2013 a las 12:00
  #9 (permalink)  
Antiguo 04/12/2013, 12:24
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: bloqueo de registros para manejar concurrencia

Cita:
creo que debo investigar un poco mas sobre las variables de usuario de mysql, y los bloqueos compartidos, creo q esa es la solucion a mi problema, voy a seguir investigando.. por ultimo .. sera que puedo capturar la variable de usuario actual de mysql? como para que ese registro del cliente que estoy trayendo con la consulta, solo me lo muestre a ese usuario conectado a la base. gracias.
No.
Vamos a ver si se entiende mejor así:

Cuando te conectas a una base de datos (cualquiera sea el DBMS), la conexión crea un espacio reservado de memoria donde existen y ocurren las acciones de ese usuario, y en ese espacio de memoria es donde existen las variables de usuario. Fuera de ese espacio, esas variables no existen.
Las bases de datos están diseñadas de modo tal que un mismo usuario podría abrir N sesiones distintas al mismo tiempo. Per cada una de esas sesiones es un bloque de memoria independiente, y no comparte nada con el resto de las sesiones abiertas. NADA. Las variables tampoco.
¿Qué implica esto?
Que tu puedes crear la variable "@a1" en cada una de esas N sesiones y darle diferentes valores dentro de cada una de ellas, y no se generan conflictos, poque cada una de ellas sólo existe en ese espacio o entorno.
La consecuencia en cuanto a "ver" las variables es más simple: Sólo pueden verse en una sesión las variables de usuario que fueron creadas en esa sesión y nada más.
¿Qué resulta de esto? Que no puedes usarlas para transferir el estado de lectura de un registro entre diferntes sesiones de usuarios, porque ellos jamás la verán en su sesión.

En otras palabras, las variables de usuario no sirven para tu caso.

¿Quieres una solución mas o menos sencilla?

Tienes dos opciones:
1) Agregar un campo a la tabla donde indiques el estado de reservado de ese registro, y que la consulta sólo pueda ver aquellos sin marca. Es algo complejo, pero funciona cuando está bien realizado.

2) Antes de guardar cualquier modificación que se haga sobre el registro leído, se debe realizar una revalidación del registro leído y asegurarse que los valores son los mismos que se leyeron. ¿Implica esto mucho más trabajo? Si, por supuesto, pero por increíble que te pueda parecer, esa es la forma elegida en todos los sistemas complejos que puedas maginar: Compañías de electricidad, bancos, telefónicas, seguros, etc.
¿por qué volver a validar todo lo ya validado?
Porque la información debe ser segura, aunque eso implique pérdida de performance.

En otras palabras: No busques una vía simple, fácil de programar y sencilla de verificar. Eso no existe.
__________________
¿A quién le enseñan sus aciertos?, si yo aprendo de mis errores constantemente...
"El problema es la interfase silla-teclado." (Gillermo Luque)
  #10 (permalink)  
Antiguo 04/12/2013, 13:05
 
Fecha de Ingreso: diciembre-2012
Mensajes: 249
Antigüedad: 11 años, 4 meses
Puntos: 2
Respuesta: bloqueo de registros para manejar concurrencia

ok muchas gracias manos a la obra!

Etiquetas: limit
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




La zona horaria es GMT -6. Ahora son las 18:48.