13.4.1. Hacer cumplir la consistencia con transacciones serializables
13.4.2. Hacer cumplir la consistencia con bloqueos de bloqueo explícitos

Es muy difícil hacer cumplir las reglas comerciales con respecto a la integridad de los datos mediante transacciones de lectura confirmada porque la vista de los datos cambia con cada declaración, e incluso una sola declaración puede no restringirse a la instantánea de la declaración si ocurre un conflicto de escritura.

Si bien una transacción de lectura repetible tiene una vista estable de los datos a lo largo de su ejecución, existe un problema sutil con el uso de instantáneas de MVCC para las comprobaciones de coherencia de datos, lo que implica algo conocido como conflictos de lectura/escritura. Si una transacción escribe datos y una transacción simultánea intenta leer los mismos datos (ya sea antes o después de la escritura), no puede ver el trabajo de la otra transacción. Entonces, el lector parece haber ejecutado primero, independientemente de cuál comenzó primero o cuál se comprometió primero. Si eso es todo, no hay problema, pero si el lector también escribe datos que son leídos por una transacción concurrente, ahora hay una transacción que parece haberse ejecutado antes que cualquiera de las transacciones mencionadas anteriormente. Si la transacción que parece haberse ejecutado en último lugar se compromete primero, es muy fácil que aparezca un ciclo en un gráfico del orden de ejecución de las transacciones. Cuando aparece un ciclo de este tipo, las comprobaciones de integridad no funcionarán correctamente sin alguna ayuda.

Como se mencionó en la Sección 13.2.3, las transacciones serializables son solo transacciones de lectura repetible que agregan monitoreo sin bloqueo para patrones peligrosos de conflictos de lectura/escritura. Cuando se detecta un patrón que podría causar un ciclo en el aparente orden de ejecución, una de las transacciones involucradas se revierte para romper el ciclo.

13.4.1. Hacer cumplir la consistencia con transacciones serializables

Si se utiliza el nivel de aislamiento de transacciones Serializable para todas las escrituras y todas las lecturas que necesitan una vista coherente de los datos, no se requiere ningún otro esfuerzo para garantizar la coherencia. El software de otros entornos que está escrito para usar transacciones serializables para garantizar la coherencia debe solo trabajo en este sentido en PostgreSQL.

Al usar esta técnica, evitará crear una carga innecesaria para los programadores de aplicaciones si el software de la aplicación pasa por un marco que vuelve a intentar automáticamente las transacciones que se revierten con una falla de serialización. Puede ser una buena idea establecer default_transaction_isolation para serializable. También sería prudente tomar alguna medida para garantizar que no se utilice ningún otro nivel de aislamiento de transacciones, ya sea sin darse cuenta o para subvertir las comprobaciones de integridad, mediante comprobaciones del nivel de aislamiento de transacciones en los activadores.

Consulte la Sección 13.2.3 para obtener sugerencias de rendimiento.

Advertencia

Este nivel de protección de integridad mediante transacciones Serializables aún no se extiende al modo de espera activo (Sección 26.5). Por eso, aquellos que usan el modo de espera en caliente pueden querer usar la lectura repetible y el bloqueo explícito en el maestro.

13.4.2. Hacer cumplir la consistencia con bloqueos de bloqueo explícitos

Cuando las escrituras no serializables son posibles, para garantizar la validez actual de una fila y protegerla contra actualizaciones simultáneas, se debe usar SELECT FOR UPDATE, SELECT FOR SHAREo un apropiado LOCK TABLE declaración. (SELECT FOR UPDATE y SELECT FOR SHARE bloquear solo las filas devueltas contra actualizaciones simultáneas, mientras que LOCK TABLE bloquea toda la tabla). Esto debe tenerse en cuenta al migrar aplicaciones a PostgreSQL desde otros entornos.

También es de destacar para aquellos que se convierten desde otros entornos el hecho de que SELECT FOR UPDATE no garantiza que una transacción simultánea no actualice o elimine una fila seleccionada. Para hacer eso en PostgreSQL, debe actualizar la fila, incluso si no es necesario cambiar ningún valor. SELECT FOR UPDATEbloquea temporalmente otras transacciones de adquirir el mismo candado o ejecutar un UPDATE o DELETE lo que afectaría la fila bloqueada, pero una vez que la transacción que mantiene este bloqueo se confirma o revierte, una transacción bloqueada continuará con la operación en conflicto a menos que un UPDATE de la fila se realizó mientras se mantenía el candado.

Las comprobaciones de validez global requieren una reflexión adicional bajo MVCC no serializable. Por ejemplo, una aplicación bancaria puede desear verificar que la suma de todos los créditos en una tabla sea igual a la suma de los débitos en otra tabla, cuando ambas tablas se actualizan activamente. Comparando los resultados de dos sucesivas SELECT sum(...) Los comandos no funcionarán de manera confiable en el modo de lectura confirmada, ya que la segunda consulta probablemente incluirá los resultados de las transacciones que la primera no contó. Hacer las dos sumas en una sola transacción de lectura repetible brindará una imagen precisa solo de los efectos de las transacciones que se comprometieron antes de que comenzara la transacción de lectura repetible, pero uno podría preguntarse legítimamente si la respuesta sigue siendo relevante en el momento en que se entrega. Si la transacción de lectura repetible aplicó algunos cambios antes de intentar realizar la verificación de consistencia, la utilidad de la verificación se vuelve aún más discutible, ya que ahora incluye algunos, pero no todos, los cambios posteriores al inicio de la transacción. En tales casos, una persona cuidadosa podría desear bloquear todas las tablas necesarias para la verificación, a fin de obtener una imagen indiscutible de la realidad actual. A SHARE El bloqueo de modo (o superior) garantiza que no haya cambios no confirmados en la tabla bloqueada, aparte de los de la transacción actual.

Tenga en cuenta también que si uno confía en el bloqueo explícito para evitar cambios simultáneos, debe usar el modo de lectura confirmada o en el modo de lectura repetible, tenga cuidado de obtener bloqueos antes de realizar consultas. Un bloqueo obtenido por una transacción de lectura repetible garantiza que no se esté ejecutando ninguna otra transacción que modifique la tabla, pero si la instantánea vista por la transacción es anterior a la obtención del bloqueo, podría ser anterior a algunos cambios confirmados en la tabla. La instantánea de una transacción de lectura repetible se congela al comienzo de su primera consulta o comando de modificación de datos (SELECT, INSERT, UPDATEo DELETE), por lo que es posible obtener bloqueos de forma explícita antes de que se congele la instantánea.

Anterior Arriba Próximo
13.3. Bloqueo explícito Casa 13.5. Advertencias