Tengo un registro de base de datos donde algunas transacciones ganan (se confirman antes del bloqueo) y otras pierden (aún no se han comprometido). Aprendimos en clase que las acciones de los perdedores deben deshacerse al revés.
¿Hay alguna razón para hacer esto al revés? ¿Alguien puede dar un ejemplo simple de un registro donde deshacer deshacer daría resultados incorrectos?
concurrency
databases
prjctdth
fuente
fuente
Respuestas:
Transacciones originales:
Deshacer hacia adelante:
fuente
Para agregar a la respuesta de DylanSp, el intento de actualizar un campo en un registro no existente fallará, pero el resultado seguirá siendo el resultado esperado: el registro r no existe.
Sin embargo, considere una situación en la que la eliminación de un registro realmente fallará:
Asumamos, no de manera poco realista, que cada OrderLine debe estar relacionada con un Order.
Ahora, revertir la transacción que comienza con la eliminación del Pedido fallará porque eso violaría nuestra regla comercial.
Así que después
Podemos terminar con un pedido existente (sin una línea de pedido).
Por supuesto, en este caso podríamos usar una eliminación en cascada, pero eso significaría que el paso 2 fallaría (sin impacto). Peor aún, puede ser un comportamiento no deseado implementar eliminaciones en cascada en los pedidos.
fuente
Vamos por analogía: digamos que vas a cenar.
Entonces recibes una llamada telefónica. Planes de cena cancelados.
Algo sale mal allí. Puede tropezar y lastimarse. O, más probablemente, se dará cuenta de que algunas acciones no se pueden deshacer hasta que las acciones posteriores se deshagan primero.
Deshacer lo último que estaba haciendo lo lleva de regreso a donde estaba cuando ocurrió el penúltimo paso. Luego deshaces ese paso y repites, retrocediendo hasta que no quede nada. Por otro lado, revertir el primer paso puede no ser posible dados los estados que siguen a los pasos posteriores.
matemáticamente hablando: las acciones pueden no conmutar, por lo que siempre que importa qué paso hagas primero o segundo, el orden en que deshagas los pasos será importante.
fuente
Esto es correcto porque las transacciones se construyen una encima de la otra y el resultado de una transacción depende en gran medida de la situación anterior a su confirmación.
Veamos las transacciones financieras:
(al principio, antes de las transacciones
a
me debe 100 USD)a
me debe 100 USD (ahora deuda total 200)a
recibe un 10% de descuento en lo que me debe. (ahora deuda total 180)Digamos que quiero cancelar las dos transacciones.
Si cancelamos el primero primero, terminaremos con:
Esto está mal, necesitamos volver a la deuda de 100. Eso será correcto si cancelamos las transacciones en orden inverso.
fuente
Suponga que hay una tabla T con una sola columna.
Suponga que el "registro de deshacer" es un archivo de base de datos que contiene transacciones no confirmadas, y que el "registro de deshacer" es un archivo de base de datos que contiene transacciones confirmadas y no confirmadas que aún no se han aplicado a los archivos de datos.
At 8:00 A.M., Transaction 100 inserts rows with values 101, 102 and 103 into table T. At 8:10 A.M., Transaction 100 is committed and the commit for transaction 100 completes. At 8:15 A.M., Transaction 200 updates row 101 to 201, 102 to 202 and 103 to 203. At 8:20 A.M., Transaction 200 has not been committed and remains in the undo log of the database. At 8:25 A.M., Transaction 300 increments each row by 50, changing row 201 to 251, 202 to 252, and 203 to 253. At 8:30 A.M., Transaction 300 has not been committed and remains in the undo log of the database. At 8:35 A.M., The instance providing access to the database crashes.
At 8:40 A.M., The instance is restarted, and the database files are opened as the instance is started:
At 8:41 A.M., The redo log has been applied, and the T table contains values 251, 252 and 253 in the instance memory.
At 8:42 A.M., The undo log is applied in the reverse order: Uncommitted transaction 300 is undone, and Uncommitted transaction 200 is undone.
¿Por qué AMBAS transacciones confirmadas y no confirmadas escritas en el archivo de registro de rehacer? La razón de esto es proporcionar una recuperación en un punto en el tiempo.
Esto significa que el contenido del archivo "redo log" NO es consistente con la transacción. Por este motivo, siempre que el registro de rehacer se use para aplicar transacciones confirmadas a los archivos de datos, el "registro de deshacer" DEBE TAMBIÉN usarse para revertir transacciones no confirmadas.
¿Por qué las transacciones en el "registro de deshacer" se revierten en el orden inverso? La transacción 300 ha agregado 50 al valor existente de cada columna de cada fila. Por lo tanto, si la transacción 200 se revierte primero, los valores cambiarán de 251, 252 y 253 a 201, 202 y 203. Si la transacción 300 se revierte en último lugar, los valores serían 151, 152 y 153, que no coinciden Los valores comprometidos originales.
Referencias
https://asktom.oracle.com/pls/asktom/f?p=100:11:0::::P11_QUESTION_ID:1670195800346464273
fuente
No es inherentemente cierto. La reversión puede simplemente volver a aplicar los bloques que se almacenaron en caché en el registro de deshacer para que el estado final sea el mismo que el estado inicial. Como el registro se escribió en orden de reenvío, hice que mi reversión también se aplicara en orden de reenvío. El orden no importó en absoluto porque la reversión volvería a intentar hasta que el archivo de registro se marcara como resuelto.
fuente