Sincronizar pool de conexiones

Me conecto a una base de datos MySQL a través de un pool de conexiones, y entre otras cosas inserto en dicha base de datos operaciones que poseen un identificador, el cual es un campo de tipo autoincrement. En el momento previo a insertar las operaciones obtengo el valor de ese identificador mediante SHOW TABLE STATUS LIKE 'operacion' porque necesito conocerlo, y seguidamente inserto la operación con un INSERT. Todo funciona bien, pero me ha surgido de repente una duda: ¿Qué ocurre si dos usuarios van a insertar sendas operaciones a la vez? ¿Para ambos se obtendrá el mismo identificador? No sé si el propio pool de conexiones se encarga de esta sincronización, o si por el contrario debo encargarme yo. En ese caso... ¿cómo debería hacerlo? Por si sirve de algo, trabajo con Struts
Si hay algo que no entediste o no te quedó claro, dímelo. No siempre uno tiene por qué haberse explicado del todo bien :)

3 Respuestas

Respuesta
1
En las versiones más recientes de mysql ya vienen algunas validaciones de integridad referncial, es decir que si ocurre un error de identificadores te lo va a hacer saber y lo que tienes que hacer es capturar el error y mandárselo al usuario. MySql tiene en su manual todas las especificaciones de los errores y como capturarlo. Tienes que implementarlo en el lenguaje que utilizas y ya.
Espero que me haya explicado y cualquier cosa, no dudes en preguntármelo.
Respecto a la integridad referencial... me has creado otra duda! Supongo que eso sí que lo hace por mí MySQL! Capturar el posible error que comentas en este sentido es simplemente capturar y manejar una SQLException, ¿no? Eso sí que lo tengo hecho así!
Realmente mi duda iba más por lo de SHOW TABLE STATUS LIKE 'operacion', que utilizo para conocer el valor del autoincrement que tendrá la sentencia INSERT que va inmediatamente después. Imagínate 2 usuarios que a la vez van a insertar una operación. El primero obtiene un valor del SHOW... de 126, el segundo obtiene un valor también de 126 (supongo yo) porque aún el primero no ha insertado!, el primero inserta con un valor de autoincrement de 126, pero el segundo lo haría con un valor de 127 y ahí ya tendría yo un error lógico!, porque en las variables en las que guardé los valores de SHOW... tengo para ambos usuarios 126! Otra cosa es que el segundo trate de insertar también con valor de 126, que no sé si realmente sucedería así, y tendríamos el problema de integridad referencial que tú dices, y supongo que se lanzaría una SQLException que mi código sí capturaría, pero el problema que te planteo yo es el otro.
De todos modos he estado mirando en la red y he visto last_insert_id(). Ya me planteé usar esto en su momento para obtener el identificador de operación asignado por autoincrement tras el INSERT, y no sé por qué lo desestimé y acabé usando el SHOW TABLE..., pero lo he estado mirando de nuevo y, aparte de no encontrarle ahora la desventaja que le vi entonces, resuelve mi problema. Si dos usuarios van a insertar a la vez, primero inserta uno, luego el otro, se obtiene el last_insert_id() para el primero, y luego para el segundo. En este caso ambos last_insert_id() son distintos porque he leído que son particulares de cada conexión. En principio esto resolvería mi problema (salvo que le encuentre otra pega), pero me gustaría saber si estoy acertado en lo que te he comentado, y si el error de integridad referencial es capturado con la SQLException
Muchas gracias por tu ayuda
Las ultimas versiones de mysql trae consigo tres características nuevas (nuevas para mysql): integridad referencial, transacciones y bloqueo de registros. Cuando alguien este utilizando tu tabla, no va a poder se utilizado por otro usuario (bloqueo de registros), si ocurrió alguna excepción tienes la integridad referencial que no te va a permitir que se repita tu porque. Usa siempre las transacciones para que cuando ocurra un error no quede nada huérfano.
Cualquier duda estoy para escucharte.
Respuesta
1
El pool de conexiones no te va a ayudar para eso, porque si no, no sería un pool :-)
La mayoría de bases de datos tienen la opción de hacer un "select for update" que en principio te debería bloquear la tabla hasta que hagas el commit. De esta forma el siguiente select for update se queda esperando a que termine el anterior.
Si con MySQL no tienes esta opción, puedes usar una tabla exclusivamente para controlar esto, actualizando siempre la misma fila antes de la operación que necesitas, así si alguien está haciendo esa operación, se tendrá que esperar a que termine.
Espero haberte ayudado. Ya me dices.
Bueno! Mirando en la red vi last_insert_id(). Ya me planteé usar esto en su momento para obtener el identificador de operación asignado por autoincrement tras el INSERT, y no sé por qué lo desestimé y acabé usando el SHOW TABLE..., pero lo he estado mirando de nuevo y, aparte de no encontrarle ahora la desventaja que le vi entonces, resuelve mi problema. Si dos usuarios van a insertar a la vez, primero inserta uno, luego el otro, se obtiene el last_insert_id() para el primero, y luego para el segundo. En este caso ambos last_insert_id() son distintos porque he leído que son particulares de cada conexión. En principio esto resolvería mi problema (salvo que le encuentre otra pega), pero me gustaría saber tu opinión sobre si realmente es así y hay algo que yo no veo.
Muchas gracias por tu ayuda
No tienes porque tener ningún problema.
Respuesta
1
Al tener un pool de conexiones se activan Flags para determinar quien llego primero, en el caso de un INSERT incrementable establece a quien darle primero el valor.
Aun así no siempre todo sucede como esperamos... monitorealo por un momento y me avisas

Añade tu respuesta

Haz clic para o

Más respuestas relacionadas