Intento escribir el código de la base de datos para asegurarme de que no esté sujeto a condiciones de carrera, para asegurarme de que he bloqueado las filas o tablas correctas. Pero a menudo me pregunto: ¿es correcto mi código? ¿Es posible forzar que se manifiesten las condiciones de carrera existentes? Quiero asegurarme de que si suceden en un entorno de producción, mi aplicación hará lo correcto.
En general, sé exactamente qué consulta simultánea puede causar un problema, pero no tengo idea de cómo obligarlos a ejecutarse simultáneamente para ver si ocurre el comportamiento correcto (por ejemplo, usé el tipo correcto de bloqueo), que los errores correctos son arrojado, etc.
Nota: Uso PostgreSQL y Perl, por lo que si esto no se puede responder genéricamente, probablemente debería volver a etiquetarse como tal.
Actualización: preferiría que la solución fuera programática. De esa manera puedo escribir pruebas automatizadas para asegurarme de que no haya regresiones.
fuente
Respuestas:
Lo hago todo el tiempo con mis módulos T-SQL.
Esencialmente, todo lo que necesita hacer es ejecutar sus módulos desde dos o más conexiones en un bucle durante un par de minutos . Por lo general, todos los problemas potenciales se exponen en unos minutos, suponiendo que tenga una caja de SQL Server con CPU decentes.
Escribí algunos ejemplos aquí y aquí .
fuente
Por lo general, trabajo con la herramienta de línea de comandos del RDBMS, solo teniendo 2 (o más) instancias de la CLI iniciadas. Luego puede reproducir uno por uno y como una carrera (que se vería como un RPG de acción) las declaraciones SQL que envía su capa de aplicación. Debe experimentar / sentir los sistemas de bloqueo en acción ya que su CLI se "colgará" un poco, esperando que los bloqueos se liberen de la otra CLI.
Si esto suena claro como el barro, no dudes en decirlo ;-)
fuente
Las condiciones de carrera requieren múltiples hilos de ejecución, por lo tanto, para realizar una prueba unitaria, deberá poder iniciar uno o más hilos. En Oracle, usaría DBMS_Scheduler para ejecutar un proceso para simular un segundo usuario. Si PostgreSQL / Perl tiene una manera de iniciar un segundo proceso mediante programación, entonces debería poder hacer algo como esto:
Proceso 1 Proceso 2
Es bueno ver pensar en cómo manejar las condiciones de carrera y, lo que es más importante, cómo probarlas en la unidad.
fuente
Siempre que bloquee las filas, no debería estar en condiciones de carrera, ya que eso generalmente se produce cuando no hay un bloqueo en su lugar.
Pero podría quedar bloqueado si una pregunta bloquea su pregunta por demasiado tiempo.
Esto es difícil de probar ya que el tiempo para las consultas puede cambiar cuando la base de datos crece.
Las consultas que funcionan bien con 100 000 filas de datos de prueba salen del gráfico con 10 000 000 filas.
Este tipo de problema puede ser muy difícil de encontrar por adelantado, pero muchos DB tienen algún método para identificar consultas lentas.
Al usar ese sistema regularmente, debería ser capaz de atrapar cualquier consulta que surja en problemas con una amplia advertencia.
Si trabajas por tu cuenta, es otra historia, pero no puedo evitarlo.
fuente
select for update
si no existieran si lo hicieran ...