sql-server locking optimistic-locking pessimistic-locking

sql server - Bloqueo optimista vs pesimista



sql-server locking (8)

Además de lo que ya se ha dicho, debe decirse que el bloqueo optimista tiende a mejorar la concurrencia a expensas de la previsibilidad. El bloqueo pesimista tiende a reducir la concurrencia, pero es más predecible.

Usted paga su dinero, etc.

Entiendo las diferencias entre el bloqueo optimista y pesimista *. Ahora, ¿podría alguien explicarme cuándo usaría alguno de ellos en general?

¿Y la respuesta a esta pregunta cambia dependiendo de si estoy usando un procedimiento almacenado para realizar la consulta?

* Pero solo para verificar, optimista significa "no bloquear la mesa durante la lectura" y pesimista significa "bloquear la tabla durante la lectura".


Básicamente hay dos respuestas más populares. El primero dice básicamente

Optimistic necesita una arquitectura de tres niveles en la que no necesariamente mantenga una conexión a la base de datos para su sesión, mientras que el bloqueo pesimista es cuando bloquea el registro para su uso exclusivo hasta que haya finalizado. Tiene una integridad mucho mejor que el bloqueo optimista, ya sea que necesite una conexión directa a la base de datos.

Otra respuesta es

el optimismo (control de versiones) es más rápido porque no tiene bloqueo, pero el bloqueo (pesimista) funciona mejor cuando la contención es alta y es mejor prevenir el trabajo en lugar de descartarlo y comenzar de nuevo.

o

El bloqueo optimista funciona mejor cuando tienes colisiones raras

Como se pone en esta página.

Creé mi respuesta para explicar cómo "mantener la conexión" se relaciona con "bajas colisiones".

Para comprender cuál es la mejor estrategia para usted, no piense en las Transacciones por segundo que tiene su base de datos, sino en la duración de una sola transacción. Normalmente, se abre la operación, se realiza una operación y se cierra la transacción. Esta es una transacción corta y clásica que ANSI tenía en mente y estaba bien para salirse con el bloqueo. Pero, ¿cómo implementa un sistema de reserva de boletos donde muchos clientes reservan las mismas habitaciones / asientos al mismo tiempo?

Usted navega por las ofertas, complete el formulario con muchas opciones disponibles y precios actuales. Lleva mucho tiempo y las opciones pueden volverse obsoletas, todos los precios no válidos entre usted comenzó a llenar el formulario y presionaron el botón "Acepto" porque no hubo un bloqueo en los datos a los que accedió y alguien más, más ágil, ha interferido. Cambiando todos los precios y necesitas reiniciar con nuevos precios.

Podrías bloquear todas las opciones mientras las lees, en su lugar. Este es un escenario pesimista. Ya ves por qué apesta. Su sistema puede ser derribado por un solo payaso que simplemente inicia una reserva y se pone a fumar. Nadie puede reservar nada antes de que termine. Su flujo de efectivo cae a cero. Por eso, las reservas optimistas se utilizan en la realidad. Quienes permanezcan demasiado tiempo deben reiniciar su reserva a precios más altos.

En este enfoque optimista, debe registrar todos los datos que lea (como en el mío Lectura repetida ) y llegar al punto de confirmación con su versión de datos (quiero comprar acciones al precio que se muestra en esta cotización, no al precio actual) ). En este punto, se crea la transacción ANSI, que bloquea la base de datos, comprueba si no se cambia nada y compromete / aborta su operación. En mi opinión, esta es una emulación efectiva de MVCC , que también está asociada con Optimistic CC y también supone que su transacción se reinicia en caso de abortar, es decir, hará una nueva reserva. Una transacción aquí implica decisiones de un usuario humano.

Estoy lejos de entender cómo implementar el MVCC de forma manual, pero creo que las transacciones de larga ejecución con opción de reinicio son la clave para comprender el tema. Corrígeme si me equivoco en alguna parte. Mi respuesta fue motivada por este capítulo de Alex Kuznecov .


El bloqueo optimista se utiliza cuando no se esperan muchas colisiones. Cuesta menos hacer una operación normal, pero si se produce la colisión, pagará un precio más alto para resolverlo a medida que se aborta la transacción.

El bloqueo pesimista se utiliza cuando se anticipa una colisión. Las transacciones que violarían la sincronización simplemente se bloquean.

Para seleccionar el mecanismo de bloqueo adecuado, debe estimar la cantidad de lecturas y escrituras y planificar en consecuencia


En la mayoría de los casos, el bloqueo optimista es más eficiente y ofrece un mayor rendimiento. Al elegir entre un bloqueo pesimista y optimista, considere lo siguiente:

  • El bloqueo pesimista es útil si hay muchas actualizaciones y posibilidades relativamente altas de que los usuarios intenten actualizar los datos al mismo tiempo. Por ejemplo, si cada operación puede actualizar una gran cantidad de registros a la vez (el banco puede agregar ganancias de intereses a cada cuenta al final de cada mes) y dos aplicaciones ejecutan dichas operaciones al mismo tiempo, tendrán conflictos. .

  • El bloqueo pesimista también es más apropiado en aplicaciones que contienen tablas pequeñas que se actualizan con frecuencia. En el caso de los llamados hotspots, los conflictos son tan probables que el bloqueo optimista desperdicia esfuerzos en deshacer las transacciones conflictivas.

  • El bloqueo optimista es útil si la posibilidad de conflictos es muy baja: hay muchos registros pero relativamente pocos usuarios, o muy pocas actualizaciones y en su mayoría operaciones de tipo lectura.


Optimistic asume que nada va a cambiar mientras lo lees.

Pesimista asume que algo lo hará y así lo bloquea.

Si no es esencial que los datos estén perfectamente leídos use optimista. Es posible que obtenga una lectura "sucia" impar, pero es mucho menos probable que provoque puntos muertos y similares.

La mayoría de las aplicaciones web están bien con lecturas sucias: en raras ocasiones, los datos no coinciden exactamente con la próxima recarga.

Para operaciones de datos exactos (como en muchas transacciones financieras) use pesimista. Es esencial que los datos se lean con precisión, sin cambios no mostrados; la sobrecarga adicional de bloqueo vale la pena.

Ah, y el servidor Microsoft SQL utiliza de forma predeterminada el bloqueo de páginas, básicamente la fila que está leyendo y algunas de las partes. El bloqueo de filas es más preciso pero mucho más lento. A menudo vale la pena establecer sus transacciones en lectura confirmada o no bloqueada para evitar puntos muertos durante la lectura.


Pensaría en un caso más cuando el bloqueo pesimista sería una mejor opción.

Para un bloqueo optimista, todos los participantes en la modificación de datos deben estar de acuerdo en utilizar este tipo de bloqueo. Pero si alguien modifica los datos sin preocuparse por la columna de la versión, esto arruinará la idea del bloqueo optimista.


Un caso de uso para el bloqueo optimista es hacer que su aplicación use la base de datos para permitir que uno de sus subprocesos / hosts "reclame" una tarea. Esta es una técnica que me ha sido útil regularmente.

El mejor ejemplo que se me ocurre es para una cola de tareas implementada usando una base de datos, con múltiples hilos que reclaman tareas simultáneamente. Si una tarea tiene el estado ''Disponible'', ''Reclamado'', ''Completado'', una consulta de db puede decir algo como "Establecer estado = ''Reclamado'' donde estado = ''Disponible''. Si varios subprocesos intentan cambiar el estado de esta manera, todos menos el primer hilo fallarán debido a datos sucios.

Tenga en cuenta que este es un caso de uso que implica solo un bloqueo optimista. Por lo tanto, como alternativa a decir "el bloqueo optimista se usa cuando no se esperan muchas colisiones", también se puede usar donde se esperan colisiones pero se quiere que una transacción sea exitosa.


El bloqueo optimista es una estrategia en la que se lee un registro, se toma nota de un número de versión (otros métodos para hacerlo incluyen fechas, marcas de hora o sumas de comprobación / hashes) y comprueban que la versión no haya cambiado antes de volver a escribir el registro. Cuando vuelve a escribir el registro, filtra la actualización en la versión para asegurarse de que sea atómica. (es decir, no se ha actualizado entre cuando verifica la versión y escribe el registro en el disco) y actualiza la versión de una vez.

Si el registro está sucio (es decir, una versión diferente a la suya), aborta la transacción y el usuario puede reiniciarla.

Esta estrategia es más aplicable a los sistemas de alto volumen y las arquitecturas de tres niveles donde no necesariamente mantiene una conexión a la base de datos para su sesión. En esta situación, el cliente no puede mantener los bloqueos de la base de datos ya que las conexiones se toman de un grupo y es posible que no esté utilizando la misma conexión de un acceso al siguiente.

El bloqueo pesimista es cuando bloquea el registro para su uso exclusivo hasta que haya terminado con él. Tiene una integridad mucho mejor que el bloqueo optimista, pero requiere que tenga cuidado con el diseño de su aplicación para evitar los Deadlocks . Para utilizar el bloqueo pesimista, necesita una conexión directa a la base de datos (como suele ser el caso en una aplicación de servidor de cliente de dos niveles ) o un ID de transacción disponible externamente que se puede usar independientemente de la conexión.

En este último caso, abre la transacción con el TxID y luego vuelve a conectarse con ese ID. El DBMS mantiene los bloqueos y le permite recuperar la sesión a través del TxID. Así es como funcionan las transacciones distribuidas que utilizan protocolos de confirmación de dos fases (como las transacciones XA o COM + ).