MySQL proporciona varios motores de base de datos para manejar las consultas SQL. Los motores más populares son MyISAM e InnoDB. De estos dos motores, InnoDB admite transacciones, lo que significa que podemos confirmar y revertir para realizar una operación que involucre múltiples consultas como una sola unidad. No es posible lo mismo con MyISAM ya que no admite transacciones. InnoDB es más confiable en comparación con MyISAM, ya que utiliza registros de transacciones para la recuperación automática.
Notas :MySQL planea eliminar completamente MyISAM ya que InnoDB tiene un rendimiento mucho mejor en comparación con MyISAM.
Este tutorial proporciona los detalles para manejar transacciones en MySQL usando START TRANSACTION, COMMIT y RETROCEDER declaraciones. Aunque podemos ejecutar las consultas SQL por separado, que es el escenario ideal, en varios casos debemos asegurarnos de que todas las consultas específicas de una tarea deben tener éxito o fallar debido a la falla de cualquiera de las consultas. Podemos considerar tales tareas como una sola unidad que involucra múltiples operaciones o consultas para crear, actualizar o eliminar filas. Por lo tanto, en una unidad transaccional que tiene múltiples operaciones, debe tener éxito o fallar.
Se debe tener cuidado al manejar las transacciones, ya que hay ciertas declaraciones que no se pueden revertir. Estos incluyen la base de datos CREATE/DROP, la tabla CREATE/ALTER/DROP o las rutinas almacenadas.
Propiedades de una Transacción
A continuación se enumeran las cuatro propiedades estándar de una transacción. Estos también se denominan como ACID .
Atomicidad - Asegura que todas las operaciones involucradas en una tarea o unidad se completen con éxito. En caso de falla de cualquiera de las operaciones, la transacción debe cancelarse y todas las operaciones anteriores deben revertirse a su estado anterior. Significa que en caso de falla de una transacción, ninguna de las operaciones involucradas en ella debe tener éxito.
Coherencia - Los datos deben estar en un estado coherente al inicio y al final de la transacción para garantizar que la base de datos cambie de estado para reflejar los cambios en una transacción confirmada con éxito.
Aislamiento - La transacción debe realizarse de forma aislada ocultando los estados intermedios con otras transacciones. Cada transacción debe operar de forma independiente y transparente entre sí.
Durabilidad - Asegura que los cambios en los datos como parte de una transacción persisten incluso en caso de falla del sistema. Los cambios no se deben deshacer incluso en caso de falla del sistema.
Declaraciones de transacciones
INICIAR TRANSACCIÓN - Podemos usar INICIAR TRANSACCIÓN o COMENZAR o COMENZAR A TRABAJAR para iniciar la transacción. El COMIENZO o COMENZAR A TRABAJAR son los alias de INICIAR TRANSACCIÓN.
COMPROMISO - En caso de éxito, el COMMIT el comando debe emitirse al final de la transacción para conservar los cambios.
RETROCEDER - En caso de cualquier falla, el ROLLBACK se debe emitir un comando para restaurar los estados como si fuera antes de iniciar la transacción.
ESTABLECER COMPROMISO AUTOMÁTICO - Utilice la instrucción SET AUTOCOMMIT para deshabilitar la confirmación automática al comienzo de la transacción y habilitarla al final de la transacción. Usar solo en caso de INICIAR TRANSACCIÓN o COMENZAR o COMENZAR A TRABAJAR no se utilizan para manejar la transacción.
Ejemplo de transferencia de dinero
Explicaré la transacción utilizando el ejemplo de transferencia de dinero intrabancaria en el que se debe transferir una cierta cantidad de dinero de una cuenta a otra dentro del mismo banco.
Notas :Este ejemplo es solo para fines de demostración y el escenario real definitivamente será diferente según las reglas bancarias. También asume que las consultas transaccionales se manejan programáticamente y los valores intermedios se almacenan en variables apropiadas.
La secuencia de operaciones para realizar la transferencia es la siguiente:
- Obtenga los ID de cliente de débito y crédito de la solicitud y guárdelos en variables.
- Obtenga el monto a transferir de la solicitud y guárdelo en una variable.
- Iniciar la transacción.
- Obtener el saldo del primer cliente y almacenar en variable.
- Obtener el saldo del segundo cliente y almacenar en variable.
- Revertir la transacción en caso de que el primer cliente no tenga saldo suficiente.
- Agregue una transacción de débito para reflejar la deducción de la primera cuenta del cliente.
- Restaurar en caso de error.
- Agregue una transacción de crédito para reflejar la transferencia a la segunda cuenta del cliente.
- Restaurar en caso de error.
- Registre la transferencia.
- Restaurar en caso de error.
- Actualizar el saldo del primer cliente.
- Restaurar en caso de error.
- Actualizar el saldo del segundo cliente.
- Restaurar en caso de error.
- Confirmar la transacción.
A continuación se mencionan las consultas de muestra para ejecutar la secuencia de transferencia.
-- Start the transaction
START TRANSACTION;
-- Get balance of first customer
SELECT balance from ACCOUNT WHERE customer_id = 123124123;
-- Get balance of second customer
SELECT balance from ACCOUNT WHERE customer_id = 223124145;
-- Rollback in case of insufficient funds
ROLLBACK;
-- Add debit transaction
INSERT INTO transaction(customer_id,amount,type,reference) VALUES(123124123, <amount>, 0, <reference>);
-- Rollback in case of failure
ROLLBACK;
-- Add credit transaction
INSERT INTO transaction(customer_id,amount,type,reference) VALUES(223124145, <amount>, 1, <reference>);
-- Rollback in case of failure
ROLLBACK;
-- Add transfer transaction
INSERT INTO transfer(from,to,amount) VALUES(123124123, 223124145, <amount>);
-- Rollback in case of failure
ROLLBACK;
-- Update balance of first customer
UPDATE ACCOUNT SET balance = <balance - amount> WHERE customer_id = 123124123;
-- Rollback in case of failure
ROLLBACK;
-- Update balance of second customer
UPDATE ACCOUNT SET balance = <balance + amount> WHERE customer_id = 223124145;
-- Rollback in case of failure
ROLLBACK;
-- Commit the transaction
COMMIT;
Podemos ver claramente que debemos retroceder en caso de falla en cualquier etapa para volver a los estados iniciales antes de comenzar la transferencia para reflejar el saldo real de ambos clientes.
Así es como podemos manejar las transacciones en MySQL.