tablas de bloqueo impide que otros usuarios DB afecte a las filas/tablas que has bloqueado. Pero los bloqueos, por sí mismos, NO garantizarán que su lógica salga en un estado consistente.
Piense en un sistema bancario.Cuando paga una factura en línea, hay al menos dos cuentas afectadas por la transacción: su cuenta, de la cual se toma el dinero. Y la cuenta del receptor, en la que se transfiere el dinero. Y la cuenta del banco, en la que felizmente depositarán todas las tarifas de servicio cargadas en la transacción. Teniendo en cuenta (como todo el mundo sabe en estos días) que los bancos son extraordinariamente estúpida, digamos que su sistema funciona así:
$balance = "GET BALANCE FROM your ACCOUNT";
if ($balance < $amount_being_paid) {
charge_huge_overdraft_fees();
}
$balance = $balance - $amount_being paid;
UPDATE your ACCOUNT SET BALANCE = $balance;
$balance = "GET BALANCE FROM receiver ACCOUNT"
charge_insane_transaction_fee();
$balance = $balance + $amount_being_paid
UPDATE receiver ACCOUNT SET BALANCE = $balance
Ahora, sin cerraduras y no hay transacciones, este sistema es vulnerable a diversas condiciones de carrera, el más grande de que son pagos múltiples que se realizan en su cuenta, o la cuenta del receptor en paralelo. Si bien su código ha recuperado su saldo y está haciendo huge_overdraft_fees() y lo que sea, es muy posible que algún otro pago ejecute el mismo tipo de código en paralelo. Recuperarán su saldo (digamos, $ 100), realizarán sus transacciones (saquen los $ 20 que están pagando y los $ 30 que les están gastando), y ahora ambos caminos de código tienen dos saldos diferentes: $ 80 y $ 70. Dependiendo de cuáles finalizan, terminará con cualquiera de esos dos saldos en su cuenta, en lugar de los $ 50 que debería haber terminado ($ 100 - $ 20 - $ 30). En este caso, "error bancario a su favor".
Ahora, digamos que usa bloqueos. Su pago de factura ($ 20) llega primero a la tubería, por lo que gana y bloquea el registro de su cuenta. Ahora tiene uso exclusivo y puede deducir los $ 20 del saldo, y devolver el nuevo saldo en paz ... y su cuenta termina con $ 80 como se esperaba. Pero ... uhoh ... Intentas actualizar la cuenta del receptor, y está bloqueado, y bloqueado más de lo que permite el código, agotando tu transacción ... Estamos lidiando con bancos estúpidos, así que en lugar de tener el error correcto manejo, el código simplemente saca un exit()
, y tus $ 20 desaparecen en una nube de electrones. Ahora está ganando $ 20, y aún le debe $ 20 al receptor, y su teléfono se vuelve a embargar.
Entonces ... ingrese las transacciones. Empieza una transacción, debita su cuenta $ 20, intenta darle crédito al receptor con $ 20 ... y algo explota de nuevo. Pero esta vez, en lugar de exit()
, el código puede simplemente hacer rollback
, y poof, tus $ 20 se agregarán mágicamente a tu cuenta.
Al final, todo se reduce a esto:
Cerraduras mantener cualquier otra persona interfiera con ningún registros de la base que está tratando. Las transacciones evitan que los errores "posteriores" interfieran con las acciones "anteriores" que haya realizado. Ninguno de los dos puede garantizar que las cosas funcionen bien al final. Pero juntos, lo hacen.
en la lección de mañana: The Joy of Deadlocks.
También estoy/todavía estoy confundido. Supongamos que la cuenta del receptor tenía $ 100 para comenzar y estamos agregando el pago de $ 20 en nuestra cuenta. Mi comprensión de las transacciones es que cuando comienzan, cualquier operación dentro de la transacción ve la base de datos en el estado que tenía al comienzo de la transacción. es decir: hasta que lo modifiquemos, la cuenta del receptor tiene $ 100. Entonces ... cuando agregamos $ 20, en realidad establecemos un saldo de $ 120. Pero, ¿qué sucede si, durante nuestra transacción, alguien agotó la cuenta del receptor a $ 0? ¿Esto es prevenido de alguna manera? ¿Obtienen mágicamente $ 120 de nuevo? ¿Es por esto que también se necesitan los bloqueos? – Russ
Sí, ahí es donde entran en juego los bloqueos. Un sistema adecuado escribiría-bloquearía el registro para que nadie más pudiera actualizar el registro mientras la transacción avanza. Un sistema paranoico pondría un bloqueo incondicional en el registro para que nadie pueda leer el balance "obsoleto" tampoco. –
Básicamente mira las transacciones como asegurando cosas dentro de la ruta del código. Bloquea cosas seguras en rutas de código "paralelas". Hasta que lleguen los bloqueos ... –