transacciones - transaction log sql server
Mejores prácticas para el procesamiento multiproceso de registros de bases de datos (5)
Aunque entiendo la intención, no estoy de acuerdo con ir al nivel de fila de bloqueo inmediatamente. Esto reducirá su tiempo de respuesta y en realidad puede empeorar su situación. Si después de la prueba está viendo problemas de concurrencia con APL, primero debe realizar un movimiento iterativo hacia el bloqueo de la "página de datos".
Para responder realmente a esta pregunta, se necesitaría más información sobre la estructura de la tabla y los índices involucrados, pero para seguir explicando.
DOL, el bloqueo de datarow usa muchos más bloqueos que el bloqueo de todas las páginas / niveles de página. La sobrecarga en la gestión de todos los bloqueos y, por lo tanto, la disminución de la memoria disponible debido a las solicitudes de más estructuras de bloqueo dentro de la memoria caché, disminuirá el rendimiento y contrarrestará las ganancias que pueda tener si adopta un enfoque más concurrente.
Pon a prueba tu enfoque sin moverte primero en APL (bloqueo de todas las páginas ''predeterminado'') y luego, si se ven problemas, muévete a DOL (página de datos primero y luego datarow). Tenga en cuenta que cuando se cambia una tabla a DOL, todas las respuestas en esa tabla empeoran, la tabla usa más espacio y la tabla se vuelve más propensa a la fragmentación, lo que requiere un mantenimiento regular.
Así que, en resumen, no te muevas directamente a Datarow prueba primero tu enfoque de concurrencia y luego si hay problemas usa primero el bloqueo de la página de datos y luego el último recurso.
Tengo un proceso único que consulta una tabla para registros donde PROCESS_IND
= ''N'', realiza algún procesamiento y luego actualiza PROCESS_IND
a ''Y''.
Me gustaría permitir que se ejecuten varias instancias de este proceso, pero no sé cuáles son las mejores prácticas para evitar problemas de concurrencia.
¿Donde debería empezar?
Convierta el procedimiento en una sola instrucción SQL y procese varias filas como un solo lote. Así es como se supone que funcionan las bases de datos.
La forma más obvia es bloquear, si su base de datos no tiene bloqueos, puede implementarlo usted mismo agregando un campo "Bloqueado".
Algunas de las formas de simplificar la concurrencia es aleatorizar el acceso a los elementos no procesados, por lo que en lugar de competir en el primer elemento, distribuyen el acceso aleatoriamente.
Debe habilitar el row level locking
en la tabla con:
CREATE TABLE mytable (...) LOCK DATAROWS
Entonces tú:
- Comience la transacción
- Seleccione su fila con la opción
FOR UPDATE
(que lo bloqueará) - Haz lo que quieras.
Ningún otro proceso puede hacer nada en esta fila hasta que finalice la transacción.
PD. Algunos mencionan problemas generales que pueden resultar del uso de LOCK DATAROWS
.
Sí, hay gastos generales, aunque difícilmente lo llamaría un problema para una mesa como esta.
Pero si cambia a DATAPAGES
, puede bloquear solo una fila por PAGE
( 2k
de forma predeterminada), y los procesos cuyas filas residen en una página no podrán ejecutarse simultáneamente.
Si hablamos de tabla con una docena de filas bloqueadas a la vez, apenas habrá una caída notable en el rendimiento.
La concurrencia de procesos es de mucha más importancia para un diseño como ese.
El patrón que utilizaría es el siguiente:
- Cree las columnas "lockedby" y "locktime" que son un thread / process / machine ID y timestamp respectivamente (necesitará el ID de la máquina al dividir el procesamiento entre varias máquinas)
Cada tarea haría una consulta como:
ACTUALIZAR taskstable SET lockedby = (my id), locktime = now () WHERE lockedby ES NULL ORDER BY ID LIMIT 10
Donde 10 es el "tamaño del lote".
- Luego, cada tarea hace un SELECCIONAR para averiguar qué filas está "bloqueado" para procesar, y procesa esas
- Después de completar cada fila, estableces lockedby y locktime en NULL
- Todo esto se hace en un bucle para tantos lotes como existen.
- Un trabajo cron, o una tarea programada, restablece periódicamente el "lockedby" de cualquier fila cuyo tiempo de bloqueo es demasiado largo, ya que presumiblemente se realizaron por una tarea que se colgó o se colgó. Alguien más los recogerá
El LIMIT 10 es específico de MySQL, pero creo que otras bases de datos tienen equivalentes. ORDER BY es import para evitar que la consulta sea no determinista.