2010-03-22 22 views
7

preliminares:MySQL: Las transacciones a través de múltiples hilos

Tengo una aplicación que mantiene una agrupación de hebras de alrededor de 100 hilos. Cada hilo puede durar de 1 a 30 segundos antes de que una nueva tarea lo reemplace. Cuando termina un hilo, ese hilo casi siempre dará como resultado la inserción de 1-3 registros en una tabla, esta tabla es utilizada por todos los hilos. En este momento, no existe soporte transaccional, pero estoy tratando de agregar eso ahora. Además, la tabla en cuestión es InnoDB. Así que ...

Meta

Quiero poner en práctica una operación de este. Las reglas para si esta transacción se compromete o revierte residen en el hilo principal. Básicamente hay una función simple que devolverá un valor booleano.

  1. ¿Puedo implementar una transacción en múltiples conexiones?
  2. De lo contrario, ¿pueden varios subprocesos compartir la misma conexión? (Nota: hay MUCHAS inserciones aquí, y ese es un requisito).

Respuesta

3

Bueno, como se indica en una respuesta diferente, no puede crear una transacción a través de múltiples conexiones. Y puede compartir la única conexión entre hilos. Sin embargo, debe tener mucho cuidado con eso. Debe asegurarse de que solo un hilo esté escribiendo en la conexión al mismo tiempo. No puede simplemente tener varios hilos hablando a través de la misma conexión sin sincronizar sus actividades de alguna manera. Es probable que sucedan cosas malas si permite que dos hilos hablen a la vez (corrupciones de memoria en la biblioteca del cliente, etc.). Usar una exclusión mutua o sección crítica para proteger las conversaciones de conexión es probablemente el camino a seguir.

-Don

+0

Tal vez, creo que podría volver a pensar esto simplemente haciendo que el hilo espere en la prueba del hilo principal para completar antes de comprometerse. – Zombies

+0

Solo un pensamiento, no probé eso: si usted hace sus propias funciones 'start_transaction()' y 'commit()'/'rollback()', y bloquea un mutex en 'start_transaction()' y lo desbloquea en la transacción fin, las transacciones serán mucho más seguras para usar en hilos. No digo que funcionará como lo hizo desde una conexión diferente. Es solo que a veces comienzas transacciones en hilos y confías en que son atómicos. También tenga en cuenta que mysql sais que solo una consulta a la vez debería ejecutarse dentro de todos los hilos. Eso incluye desde la ejecución de la consulta hasta completar la obtención del resultado. – NickSoft

+0

La comunicación sobre la conexión debe ser serializada. Un enfoque es tener un hilo de comunicación dedicado y hacer que otros hilos hagan el trabajo que sea necesario, luego pasar los resultados al hilo de comunicación, que serializa los enunciados. –

4

1) No, una transacción está limitada a una única conexión de base de datos.

2) Sí, una conexión (y transacción) se puede compartir en varios subprocesos.

+0

cuanto a (2), y si la tabla es INNODB, I considerar que es seguro tener múltiples inserciones ocurren simultáneamente? – Zombies

+0

@Zombies Sí, aunque no tengo experiencia con InnoDB y Transactions, creo que debería estar bien. No veo ninguna razón para que no funcione. –

0

Compartir conexiones entre muchos subprocesos generalmente se implementa mediante el uso de un grupo de conexiones. Cada hilo puede solicitar una conexión desde el conjunto, usarlo para sus fines (una o más transacciones, comprometidas o retrotraídas) y devolverlo al grupo una vez que la tarea haya finalizado.

Esto es lo que los servidores de aplicaciones le ofrecen. También se encargarán de las transacciones, i. mi. cuando el método que solicitó la transacción finaliza normalmente, se confirman los cambios, si arroja una excepción, la transacción de la base de datos se revierte.

Sugiero que eche un vistazo a Java EE 5 o 6 - es muy fácil de usar e incluso se puede emplear en sistemas integrados. Para un comienzo fácil, eche un vistazo a Netbeans y al servidor de aplicaciones Glassfish. Sin embargo, los conceptos generales se aplican a todos los servidores de aplicaciones por igual.

En cuanto a InnoDB, no tendrá ningún problema para manejar muchas transacciones. Bajo la supervisión del servidor de aplicaciones, puede concentrarse en la lógica de negocios y no tiene que preocuparse por las actualizaciones a medio escribir ni por que nadie vea las actualizaciones/inserciones antes de que se haya confirmado la transacción de la que provienen.

InnoDB utiliza MVCC (control de concurrencia de varias versiones), presentando de manera efectiva cada transacción con una instantánea de toda la base de datos a partir del momento en que se inició. Puede leer más acerca de MVCC aquí en una pregunta relacionada: Question 812512

+0

Esto no se implementará en J2EE. Pero usará un grupo de conexiones J2SE en el futuro sí. Entonces, ¿puedo considerar que puedo retroceder en todas las conexiones en el grupo de conexiones ...? – Zombies

+0

Sí, MVCC se establece de forma predeterminada en un nivel de aislamiento de transacciones de "lectura repetible", lo que significa que una vez que una transacción ha leído el primer bit de datos, no verá ninguna actualización de otras transacciones, incluso si están comprometidas. Solo cuando la transacción actual se comprometa o se retrotraiga, la siguiente transacción en esta conexión verá los nuevos datos de todos los demás que se hayan comprometido hasta ese momento. –

+0

Para que quede claro: no podrá emitir un solo comando "deshacer todas las transacciones abiertas". Pero de todos modos, esto no es lo que querrías, de ser así, creo que debes arrojar más luz sobre tu sistema, porque no parece correcto. –

Cuestiones relacionadas