Anda di halaman 1dari 7

Transacciones

Las transacciones son un concepto fundamental de todos los sistemas de


bases de datos. El punto esencial de una transaccin es su capacidad para
empaquetar varios pasos en una sola operacin todo o nada. Los estados
intermedios entre los pasos no son visibles para otras transacciones
concurrentes, y si ocurre alguna falla que impida que se complete la
transaccin, entonces ninguno de los pasos se ejecuta y no se afecta la base
de datos en absoluto.

EJEMPLO 1
Trabajaremos con la base de datos Northwind en nuestros ejemplos.
Vamos a realizar una transaccin que modifica el precio de dos productos de la
base de datos.
USE NorthWind
DECLARE @Error int
--Declaramos una variable que utilizaremos para almacenar un posible
cdigo de error
BEGIN TRAN
--Iniciamos la transaccin
UPDATE Products SET UnitPrice=50 WHERE ProductName =Chai
--Ejecutamos la primera sentencia
SET @Error=@@ERROR
--Si ocurre un error almacenamos su cdigo en @Error

--y saltamos al trozo de cdigo que deshar la transaccin. S, eso de ah


es un
--GOTO, el demonio de los programadores, pero no pasa nada por usarlo
--cuando es necesario
IF (@Error<>0) GOTO TratarError
--Si la primera sentencia se ejecuta con xito, pasamos a la segunda
UPDATE Products SET UnitPrice=50 WHERE ProductName=Chang
SET @Error=@@ERROR
--Y si hay un error hacemos como antes
IF (@Error<>0) GOTO TratarError
--Si llegamos hasta aqu es que los dos UPDATE se han completado con
--xito y podemos "guardar" la transaccin en la base de datos
COMMIT TRAN
TratarError:
--Si ha ocurrido algn error llegamos hasta aqu
If @@Error<>0 THEN
BEGIN
PRINT Ha ecorrido un error. Abortamos la transaccin
--Se lo comunicamos al usuario y deshacemos la transaccin
--todo volver a estar como si nada hubiera ocurrido
ROLLBACK TRAN
END
Como se puede ver para cada sentencia que se ejecuta miramos si se ha
producido o no un error, y si detectamos un error ejecutamos el bloque de
cdigo que deshace la transaccin.

Hay una interpretacin incorrecta en cuanto al funcionamiento de las


transacciones que esta bastante extendida. Mucha gente cree que si tenemos
varias sentencias dentro de una transaccin y una de ellas falla, la transaccin
se aborta en su totalidad.
Nada ms lejos de la realidad!
Si tenemos dos sentencias dentro de una transaccin.
USE NorthWind
BEGIN TRAN
UPDATE Products SET UnitPrice=50 WHERE ProductName=Chang
UPDATE Products SET UnitPrice=50 WHERE ProductName=Chang
COMMIT TRAN
Estas dos sentencias se ejecutarn como una sola. Si por ejemplo en medio de
la transaccin (despus del primer update y antes del segundo) hay un corte de
electricidad, cuando el SQL Server se recupere se encontrar en medio de una
transaccin y, o bien la termina o bien la deshace, pero no se quedar a
medias.
El error est en pensar que si la ejecucin de la primera sentencia da un error
se cancelar la transaccin. El SQL Server slo se preocupa de ejecutar las
sentencias, no de averiguar si lo hacen correctamente o si la lgica de la
transaccin es correcta. Eso es cosa nuestra.
Por eso en el ejemplo que tenemos ms arriba para cada sentencia de nuestro
conjunto averiguamos si se ha producido un error y si es as actuamos en
consecuencia cancelando toda la operacin.

EJEMPLO 2
Considere una base de datos bancaria que contiene balances de varias
cuentas de clientes y balances totales de depsito de sucursales. Suponga que
queremos registrar un pago de $100 de la cuenta de Alicia a la de Roberto.
Simplificando la operacin exageradamente, las rdenes SQL para hacerlo se
veran as:

UPDATE cuentas SET balance = balance - 160.00 WHERE nombre = 'Alicia';


UPDATE sucursales SET balance = balance - 160.00 WHERE nombre =
(SELECT sucursal FROM cuentas WHERE nombre = 'Alicia');
UPDATE cuentas SET balance = balance + 160.00 WHERE nombre =
'Roberto';
UPDATE sucursales SET balance = balance + 160.00 WHERE nombre =
(SELECT sucursal FROM cuentas WHERE nombre = 'Roberto');

Los detalles de estas rdenes no son importantes en este momento; lo que


importa es que hay varias actualizaciones separadas involucradas para lograr
esta operacin ms o menos sencilla. Los operadores bancarios van a querer
estar seguros de que o todos estos pasos se ejecutan o no se ejecuta ninguno.
Definitivamente no sera aceptable si una falla del sistema resulta en que
Roberto recibe $100 que no fueron debitados de la cuenta de Alicia. Tampoco
si a Alicia le debitaran y a Roberto no le abonaran. Se necesita una garanta de
que si algo sale mal en el transcurso de la operacin, ninguno de los pasos
ejecutados hasta el momento tendrn efecto. Para el ejemplo anterior, agrupar
las actualizaciones en una transaccin proporciona esa garanta. De las
transacciones se dice que son atmicas: desde el punto de vista de otras
transacciones, la transaccin ocurre completamente o no ocurre en absoluto.

Tambin es necesario garantizar que, despus que se complete una


transaccin y que el sistema de bases de datos tenga completo conocimiento
de ella, realmente el registro haya sido permanente y que este no se perder,
incluso si llega a suceder una falla poco tiempo despus. Por ejemplo, si se

estuviera registrando un retiro de Roberto, no sera aceptable que el dbito de


su cuenta desapareciera en una falla del sistema justo despus de que l sale
del banco. Una base de datos transaccional garantiza que todas las
actualizaciones realizadas por una transaccin se grabarn en un medio de
almacenamiento permanente (en disco, por ejemplo) antes de que la
transaccin se reporte completamente.
Otra propiedad importante de las bases de datos transaccionales se relaciona
con la nocin de las actualizaciones atmicas: cuando hay muchas
transacciones concurrentes, ninguna de ellas debera conocer los cambios
incompletos hechos por las dems. Por ejemplo, si alguna transaccin est
ocupada totalizando todos los balances de una sucursal, no servira que
incluyera el dbito de la sucursal de Alicia pero no el crdito a la sucursal de
Roberto, ni viceversa. As que las transacciones deben ser todo o nada, no
solamente en trminos de su efecto permanente en la base de datos, sino
tambin en trminos de su visibilidad a medida que suceden. Las
actualizaciones hechas hasta cierto momento por una transaccin abierta son
invisibles para las dems transacciones hasta que la transaccin se complete.
A partir de su finalizacin, todas las actualizaciones se hacen visibles
simultneamente.

En PostgreSQL, una transaccin se indica encerrando las rdenes SQL de la


transaccin entre las rdenes BEGIN y COMMIT. Entonces la transaccin
bancaria del ejemplo de arriba se vera as:
BEGIN;
UPDATE cuentas SET balance = balance - 160.00 WHERE nombre = 'Alicia';
-- etc etc
COMMIT;

Si en medio de una transaccin se decide que ya no se quiere registrar los


cambios (tal vez el balance de Alicia se volvi negativo en algn momento, por
ejemplo), se puede recurrir a la orden ROLLBACK en lugar de COMMIT y todas
las actualizaciones hasta ese punto quedaran canceladas.

De hecho, PostgreSQL trata cada declaracin de SQL como si se estuviera


ejecutando dentro de una transaccin. Si uno no especifica una orden BEGIN,
entonces cada declaracin individual tiene un BEGIN y, si es exitosa, un
COMMIT alrededor de ella. Algunas veces, a un grupo de declaraciones
encerradas entre BEGIN y COMMIT se les llama un bloque de transaccin.
Es posible controlar las declaraciones en una transaccin de una manera ms
granular por medio de puntos de recuperacin (savepoints). Los puntos de
recuperacin permiten descartar selectivamente algunas partes de la
transaccin mientras las dems s se ejecutan. Despus de definir un punto de
recuperacin con SAVEPOINT, se puede volver a l si es necesario por medio
de ROLLBACK TO. Todos los cambios de la base de datos hechos por la
transaccin entre el punto de recuperacin y el rollback se descartan, pero los
cambios hechos antes del punto de recuperacin se mantienen.

Despus de volver a un punto de recuperacin, este ltimo sigue definido, o


sea que se puede volver a l varias veces. Y al contrario, si uno est seguro de
que no necesita volver a un punto de recuperacin particular otra vez, entonces
puede liberarlo para que el sistema ahorre algunos recursos. Tenga en cuenta
que tanto liberar un punto de recuperacin como volver a l liberar
automticamente todos los puntos de recuperacin definidos despus de l.

Todo esto sucede dentro del bloque de transaccin, por lo tanto nada es visible
para otras sesiones de la base de datos. Cuando se ejecuta el bloque de
transaccin, las acciones ejecutadas se hacen visibles como una unidad para
otras sesiones, mientras que las acciones de rollback nunca se hacen visibles.
Retomando el ejemplo de la base de datos bancaria, suponga que se debitan
$100 de la cuenta de Alicia y se abonan a la cuenta de Roberto, pero que
despus resulta que se debi abonar a la cuenta de Walter. Esto se podra
hacer usando un punto de recuperacin:
BEGIN;

UPDATE cuentas SET balance = balance - 160.00 WHERE nombre = 'Alicia';


SAVEPOINT mi_savepoint;
UPDATE cuentas SET balance = balance + 160.00 WHERE nombre =
'Roberto';
-- Uy ... no era la cuenta de Roberto sino la de Walter
ROLLBACK TO mi_savepoint;
UPDATE cuentas SET balance = balance + 160.00 WHERE nombre = 'Walter';
COMMIT;

Este ejemplo, claro, est sobre simplificado, pero existe mucha posibilidad de
control en un bloque de transaccin por medio de los puntos de recuperacin.
Es ms, ROLLBACK TO es la nica manera de retomar el control de un bloque
de transaccin puesto en estado de aborto por el sistema debido a un error,
devolverlo completamente y reiniciarlo.

Anda mungkin juga menyukai