2008-09-17 14 views
6

Estoy usando mysql ++ para conectarme a una base de datos MySQL y realizar un montón de consultas de datos. Debido a que las tablas de las que estoy leyendo se escriben constantemente, y que necesito una vista coherente de los datos, primero cierro las tablas. Sin embargo, MySQL no tiene el concepto de 'NOWAIT' en su consulta de bloqueo, por lo tanto, si las tablas están bloqueadas por otra cosa que las mantiene bloqueadas durante un tiempo prolongado, mi aplicación espera ahí. Lo que quiero que haga es poder regresar y decir algo como "No se pudo obtener el bloqueo" y volver a intentarlo en unos segundos. Mi intento general de este tiempo de espera es más abajo.Cómo agotar el tiempo de espera de una consulta de mysql ++ en C++

Si ejecuto esto después de bloquear la tabla en la base de datos, recibo el mensaje de que se agotó el tiempo de espera, pero no sé cómo terminar la línea mysql_query para terminar. Agradecería cualquier ayuda/ideas!


volatile sig_atomic_t success = 1; 

void catch_alarm(int sig) { 
     cout << "Timeout reached" << endl; 
     success = 0; 
     signal(sig,catch_alarm); 
} 

// connect to db etc. 
// *SNIP 

signal (SIGALRM, catch_alarm); 
alarm(2); 
mysql_query(p_connection,"LOCK TABLES XYZ as write"); 

Respuesta

0

Puede ejecutar la consulta de bloqueo en un subproceso diferente y nunca se molesta con el tiempo de espera. Cuando llegan algunos datos, notifica el hilo que necesita saber sobre el estado de la transacción.

0

Si escribo desde cero, lo haría, pero esta es una aplicación de servidor a la que solo estamos haciendo una actualización en lugar de una gran repetición.

0

en lugar de intentar falsificar transacciones con bloqueos de tabla, ¿por qué no cambiar a tablas innodb donde obtiene transacciones reales? solo asegúrese de establecer el nivel de aislamiento de transacción predeterminado en REPEATABLE READ.

0

Como dije, no es tan fácil "cambiar" o volver a diseñar cuando se trata de un sistema en vivo, en producción. Estoy un poco frustrado de que MySQL no proporcione métodos para verificar bloqueos o elegir no colgar esperando en un bloqueo.

0

No sé si esto es una buena idea en términos de uso de recursos y "mejores prácticas" y "limpieza" y todo lo demás ... pero ahora ha descrito repetidamente las esposas que lo atan en términos de volver a diseñar un sistema "limpio" ... así que aquí va .....

¿Podría abrir una nueva conexión por separado solo para enviar la instrucción LOCK? ¿Entonces cierra esa conexión cuando detecte la alarma de tiempo de espera? Al cerrar/destruir la conexión que estaba dedicada a la instrucción LOCK, ¿no sería esencialmente "cancelar" la declaración LOCK? No estoy seguro si ocurrirán tales eventos como he descrito/adivinado, pero tal vez sea algo para probar.

0

Mi experiencia descrita hasta ahora me indica que el cierre de una conexión en la que se está ejecutando una consulta provoca un error de seg. Por lo tanto, enviar esa consulta a una conexión diferente no sería de gran ayuda, ya que eso también daría lugar a un error.

3

Se puede implementar un comportamiento "similar a cancelar" de esta manera:

ejecutar la consulta en un hilo separado, que sigue funcionando si se produce o no el tiempo de espera. El tiempo de espera se produce en el hilo principal y establece una variable en "1" que indica que ocurrió. Luego haces lo que quieras hacer en tu hilo principal.

El hilo de consulta, una vez que se completa la consulta, comprueba si se ha producido el tiempo de espera. Si no es así, hace el resto del trabajo que necesita hacer. Si lo TIENE, simplemente desbloquea las tablas que acaba de cerrar.

Sé que suena un poco derrochador, pero el período de desbloqueo de bloqueo debe ser básicamente instantáneo, y se obtiene lo más cerca posible del resultado que desea.

Cuestiones relacionadas