Entiendo las diferencias entre el bloqueo optimista y pesimista. ¿Podría alguien explicarme cuándo usaría cualquiera de ellos en general?
¿Y la respuesta a esta pregunta cambia dependiendo de si estoy usando o no un procedimiento almacenado para realizar la consulta?
Pero solo para verificar, optimista significa "no bloquear la mesa mientras lee" y pesimista significa "bloquear la mesa mientras lee".
sql-server
locking
optimistic-locking
pessimistic-locking
Jason Baker
fuente
fuente
At any technique type conflicts should be detected and considered, with similar overhead for both materialized and non-materialized conflicts
.Respuestas:
El bloqueo optimista es una estrategia en la que lee un registro, toma nota de un número de versión (otros métodos para hacerlo incluyen fechas, marcas de tiempo o sumas de verificación / hashes) y comprueba que la versión no ha 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 un solo golpe.
Si el registro está sucio (es decir, una versión diferente a la suya), cancela la transacción y el usuario puede reiniciarla.
Esta estrategia es más aplicable a sistemas de alto volumen y arquitecturas de tres niveles en los que 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 a otro.
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 puntos muertos . Para usar 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 pueda usar independientemente de la conexión.
En el último caso, abre la transacción con el TxID y luego se vuelve a conectar con esa 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 XA o COM + Transacciones ).
fuente
El bloqueo optimista se utiliza cuando no se esperan muchas colisiones. Hacer una operación normal cuesta menos, pero si se produce la colisión, pagaría un precio más alto para resolverla a medida que se anula la transacción.
El bloqueo pesimista se usa cuando se anticipa una colisión. Las transacciones que violarían la sincronización simplemente están bloqueadas.
Para seleccionar el mecanismo de bloqueo adecuado, debe estimar la cantidad de lecturas y escrituras y planificar en consecuencia.
fuente
Optimistic asume que nada va a cambiar mientras lo estás leyendo.
Pesimista asume que algo lo hará y así lo bloquea.
Si no es esencial que los datos se lean perfectamente, utilice optimista. Es posible que obtenga una lectura 'sucia' extraña, pero es mucho menos probable que produzca puntos muertos y similares.
La mayoría de las aplicaciones web están bien con lecturas sucias: en la rara ocasión los datos no coinciden exactamente con la próxima recarga.
Para operaciones de datos exactas (como en muchas transacciones financieras) use pesimista. Es esencial que los datos se lean con precisión, sin cambios no mostrados; la sobrecarga de bloqueo adicional lo vale.
Ah, y el servidor Microsoft SQL predeterminado es el bloqueo de página, básicamente la fila que está leyendo y algunas a cada lado. El bloqueo de fila es más preciso pero mucho más lento. A menudo vale la pena configurar sus transacciones para lectura comprometida o sin bloqueo para evitar puntos muertos mientras lee.
fuente
Además de lo que ya se ha dicho:
optimistic
bloqueo tiende a mejorar la concurrencia a expensas de la previsibilidad.Pessimistic
el bloqueo tiende a reducir la concurrencia, pero es más predecible. Usted paga su dinero, etc.fuente
Cuando se trata de conflictos, tiene dos opciones:
Ahora, consideremos la siguiente anomalía de actualización perdida :
La anomalía de la actualización perdida puede ocurrir en el nivel de aislamiento de lectura comprometida .
En el diagrama de arriba podemos ver que Alice cree que puede retirar 40 de ella,
account
pero no se da cuenta de que Bob acaba de cambiar el saldo de la cuenta, y ahora solo quedan 20 en esta cuenta.Bloqueo pesimista
El bloqueo pesimista logra este objetivo al tomar un bloqueo compartido o de lectura en la cuenta para evitar que Bob cambie la cuenta.
En el diagrama anterior, tanto Alice como Bob adquirirán un bloqueo de lectura en la
account
fila de la tabla que ambos usuarios han leído. La base de datos adquiere estos bloqueos en SQL Server cuando utiliza lectura repetible o serializable.Debido a que tanto Alice como Bob han leído el
account
con el valor PK de1
, ninguno de ellos puede cambiarlo hasta que un usuario libere el bloqueo de lectura. Esto se debe a que una operación de escritura requiere una adquisición de bloqueo de escritura / exclusiva, y los bloqueos compartidos / leídos evitan bloqueos de escritura / exclusivos.Solo después de que Alice haya comprometido su transacción y se haya liberado el bloqueo de lectura en la
account
fila, BobUPDATE
reanudará y aplicará el cambio. Hasta que Alice libere el bloqueo de lectura, la ACTUALIZACIÓN de Bob se bloquea.Bloqueo optimista
El bloqueo optimista permite que ocurra el conflicto, pero lo detecta al aplicar la ACTUALIZACIÓN de Alice a medida que la versión ha cambiado.
Esta vez, tenemos una
version
columna adicional . Laversion
columna se incrementa cada vez que se ejecuta UPDATE o DELETE, y también se usa en la cláusula WHERE de las declaraciones UPDATE y DELETE. Para que esto funcione, necesitamos emitir SELECT y leer el actualversion
antes de ejecutar UPDATE o DELETE, de lo contrario, no sabríamos qué valor de versión pasar a la cláusula WHERE o incrementar.Transacciones a nivel de aplicación
Los sistemas de bases de datos relacionales han surgido a fines de los años 70 y principios de los 80, cuando un cliente, típicamente, se conectaba a una unidad central a través de un terminal. Es por eso que todavía vemos que los sistemas de bases de datos definen términos como la configuración de SESIÓN.
Hoy en día, a través de Internet, ya no ejecutamos lecturas y escrituras en el contexto de la misma transacción de base de datos, y ACID ya no es suficiente.
Por ejemplo, considere el siguiente caso de uso:
Sin un bloqueo optimista, no hay forma de que esta actualización perdida se haya detectado incluso si las transacciones de la base de datos utilizaran Serializable. Esto se debe a que las lecturas y escrituras se ejecutan en solicitudes HTTP separadas, por lo tanto, en diferentes transacciones de la base de datos.
Por lo tanto, el bloqueo optimista puede ayudarlo a evitar Actualizaciones Perdidas incluso cuando utiliza transacciones a nivel de aplicación que también incorporan el tiempo de reflexión del usuario.
Conclusión
El bloqueo optimista es una técnica muy útil, y funciona bien incluso cuando se usan niveles de aislamiento menos estrictos, como lectura confirmada, o cuando las lecturas y escrituras se ejecutan en transacciones de bases de datos posteriores.
La desventaja del bloqueo optimista es que el marco de acceso a datos desencadenará una reversión al capturar una
OptimisticLockException
, por lo tanto, perderá todo el trabajo que hemos realizado anteriormente en la transacción que se está ejecutando actualmente.A mayor contención, más conflictos y mayores posibilidades de abortar las transacciones. Las reversiones pueden ser costosas para el sistema de base de datos, ya que necesita revertir todos los cambios pendientes actuales que pueden involucrar tanto las filas de la tabla como los registros de índice.
Por esta razón, el bloqueo pesimista puede ser más adecuado cuando los conflictos ocurren con frecuencia, ya que reduce la posibilidad de revertir las transacciones.
fuente
PESSIMISTIC_FORCE_INCREMENT
.Pensaría en un caso más cuando el bloqueo pesimista sería una mejor opción.
Para un bloqueo optimista, cada participante en la modificación de datos debe estar de acuerdo en usar este tipo de bloqueo. Pero si alguien modifica los datos sin preocuparse por la columna de versión, esto arruinará toda la idea del bloqueo optimista.
fuente
Básicamente hay dos respuestas más populares. El primero básicamente dice
Otra respuesta es
o
Como se pone en esta página.
Creé mi respuesta para explicar cómo se relaciona "mantener conexión" con "colisiones bajas".
Para comprender qué estrategia es mejor 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, usted abre la operación de trasnación, performa y cierra la transacción. Esta es una transacción corta y clásica que ANSI tenía en mente y bien para salirse con la suya. Pero, ¿cómo implementa un sistema de reserva de boletos donde muchos clientes reserven las mismas habitaciones / asientos al mismo tiempo?
Explore 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 comenzaron a llenar el formulario y presionaron el botón "Acepto" porque no había ningún bloqueo en los datos a los que accedieron y alguien más, más ágil, intervino cambiando todos los precios y necesita reiniciar con nuevos precios.
En su lugar, puede bloquear todas las opciones a medida que las lee. 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 deja de fumar. Nadie puede reservar nada antes de que termine. Su flujo de caja cae a cero. Por eso, las reservas optimistas se utilizan en la realidad. Aquellos que se demoran demasiado tienen que reiniciar su reserva a precios más altos.
En este enfoque optimista, debe registrar todos los datos que lee (como en la lectura repetida mía ) y llegar al punto de confirmación con su versión de datos (quiero comprar acciones al precio que mostró en esta cotización, no al precio actual ) En este punto, se crea la transacción ANSI, que bloquea la base de datos, verifica si no se ha cambiado nada y confirma / cancela 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 cancelación, es decir, hará una nueva reserva. Una transacción aquí implica decisiones de un usuario humano.
Estoy lejos de comprender cómo implementar el MVCC manualmente, pero creo que las transacciones de larga duració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 .
fuente
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, tenga en cuenta 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 tales 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 estos llamados puntos calientes, los conflictos son tan probables que el bloqueo optimista desperdicia el esfuerzo en revertir las transacciones en conflicto.
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 principalmente operaciones de tipo lectura.
fuente
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 hilos / 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 base de datos puede decir algo como "Establecer estado = 'Reclamado' donde estado = 'Disponible'. Si varios hilos 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. Entonces, 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 desea que una transacción tenga éxito.
fuente
Se han dicho muchas cosas buenas sobre el bloqueo optimista y pesimista. Un punto importante a considerar es el siguiente:
Cuando se utiliza el bloqueo optimista, debemos tener cuidado con el hecho de que la aplicación se recuperará de estas fallas.
Especialmente en arquitecturas controladas por mensajes asíncronos, esto puede conducir a un procesamiento de mensajes fuera de servicio o actualizaciones perdidas.
Los escenarios de fallas deben ser pensados.
fuente