Cuando una sola persona trabaja con la base de datos, todo funciona sin contratiempos. Pero cuando cien usuarios acceden al mismo tiempo, los problemas de concurrencia aparecen y pueden comprometer tanto la integridad de los datos como el rendimiento del servidor. Comprender cómo SQL Server gestiona múltiples sesiones simultáneas es fundamental para cualquier profesional que administre bases de datos en producción.
¿Qué problemas genera la concurrencia en bases de datos?
Antes de aplicar soluciones, es necesario identificar los tres errores clásicos que surgen cuando varias sesiones acceden a los mismos datos de forma simultánea.
¿Qué es una lectura sucia o dirty read?
Una lectura sucia ocurre cuando una sesión lee datos que otra sesión modificó pero aún no confirmó con commit [01:55]. En la demostración con dos sesiones paralelas en SQL Server, la sesión A actualiza un pedido y espera diez segundos sin hacer commit. Mientras tanto, la sesión B lee ese dato modificado. Cuando la sesión A ejecuta un rollback, el valor que leyó la sesión B nunca existió realmente. Es información basura que podría contaminar reportes o decisiones.
¿Cómo funciona el non-repeatable read?
Este error se produce al leer el mismo dato dos veces dentro de una misma transacción y obtener valores distintos [03:24]. La analogía es clara: estás viendo un partido de fútbol por televisión, miras el marcador en tu teléfono y dice dos a uno, pero minutos después dice tres a uno sin que hayas visto ningún gol. En código, la sesión A consulta el total de pedidos, espera diez segundos y vuelve a consultar. Durante esa espera, la sesión B ejecuta un update sobre la misma tabla [04:28]. El resultado: la primera lectura arroja 9.999 y la segunda arroja 600. Para un procedimiento almacenado que demora veinte minutos, esto significa que sus resultados no son confiables.
¿Qué diferencia al phantom read de los otros errores?
El phantom read aparece cuando una agregación devuelve resultados distintos en diferentes momentos de la misma transacción [06:17]. A diferencia del non-repeatable read que afecta una fila específica, el phantom read se manifiesta en conteos o sumas. En la demostración, la sesión A cuenta diecinueve pedidos del mes uno, pero mientras espera, la sesión B inserta un nuevo pedido. Al volver a contar, aparecen veinte elementos. Es una lectura fantasma: datos que no estaban considerados al inicio de la transacción.
¿Qué niveles de aislamiento ofrece SQL Server?
Los niveles de aislamiento son el mecanismo para balancear integridad y rendimiento según las necesidades de cada escenario [07:47].
- Read Uncommitted: el más permisivo, permite lecturas sucias y nunca bloquea. Útil para dashboards en tiempo real donde la exactitud no es crítica.
- Read Committed: el nivel por defecto en SQL Server. Previene lecturas sucias usando bloqueos de lectura compartidos. La mayoría de los sistemas funciona bien con este nivel [08:33].
- Repeatable Read: además de prevenir lecturas sucias, evita el non-repeatable read. Mantiene bloqueos compartidos hasta el fin de la transacción, lo que genera mayor contención [09:05].
- Serializable: el más restrictivo. Previene también los phantom reads bloqueando rangos completos de filas. Ofrece máxima integridad pero mínima concurrencia [09:37].
Para cambiar el nivel en una sesión, se ejecuta SET TRANSACTION ISOLATION LEVEL seguido del nivel deseado [10:05]. Este cambio aplica únicamente a la sesión actual del usuario. A nivel de query individual, se puede usar el hint NOLOCK, equivalente a Read Uncommitted, muy utilizado en producción para reportes de lectura [11:04].
¿Qué es RCSI y cómo resuelve bloqueos entre lectores y escritores?
El Read Committed Snapshot Isolation (RCSI) es la mejor práctica moderna en SQL Server [12:13]. Su principio es simple: los lectores nunca bloquean a los escritores y los escritores nunca bloquean a los lectores. Los SELECT y los INSERT/UPDATE coexisten sin interferencia.
Para activarlo se ejecuta: ALTER DATABASE TiendaLatam SET READ_COMMITTED_SNAPSHOT ON [12:55]. Este es el comportamiento que viene por defecto en Azure SQL Database.
Un concepto relacionado es el deadlock, que aparece cuando dos sesiones se bloquean mutuamente esperando que la otra libere un recurso [13:15]. SQL Server lo detecta automáticamente y termina una de las sesiones, conocida como la víctima.
La regla práctica es usar Read Committed como punto de partida, implementar RCSI como mejora inmediata y reservar los niveles más restrictivos para situaciones que lo justifiquen con criterio técnico. Si trabajas con reportes de Power BI que se actualizan en tiempo real con cincuenta usuarios simultáneos, elegir correctamente el nivel de aislamiento marca la diferencia entre datos confiables y resultados inconsistentes.
¿Qué nivel de aislamiento usarías para reportes de venta diarios? ¿Activarías RCSI en tu entorno de producción? Comparte tus argumentos técnicos en los comentarios.