Hay una interpretación
incorrecta en cuanto al funcionamiento de las transacciones que esta bastante
extendida. Mucha gente cree que si tenemos varias sentencias dentro de
una transacción y una de ellas falla, la transacción se aborta
en su totalidad.
¡Nada más lejos
de la realidad!
Si tenemos dos sentencias
dentro de una transacción.
USE
NorthWind
BEGIN
TRAN
UPDATE
Products SET UnitPrice=20 WHERE ProductName=Chang
UPDATE
Products SET UnitPrice=20 WHERE ProductName=Chang
COMMIT
TRAN
Estas dos sentencias se ejecutarán
como una sola. Si por ejemplo en medio de la transacción (después
del primer update y antes del segundo) hay un corte de electricidad, cuando
el SQL Server se recupere se encontrará en medio de una transacción
y, o bien la termina o bien la deshace, pero no se quedará a medias.
El error está en pensar
que si la ejecución de la primera sentencia da un error se cancelará
la transacción. El SQL Server sólo se preocupa de ejecutar
las sentencias, no de averiguar si lo hacen correctamente o si la lógica
de la transacción es correcta. Eso es cosa nuestra.
Por eso en el ejemplo que
tenemos más arriba para cada sentencia de nuestro conjunto averiguamos
si se ha producido un error y si es así actuamos en consecuencia
cancelando toda la operación.
Transacciones anidadas
Otra de las posibilidades
que nos ofrece el SQL Server es utilizar transacciones anidadas.
Esto quiere decir que podemos
tener transacciones dentro de transacciones, es decir, podemos empezar
una nueva transacción sin haber terminado la anterior.
Asociada a esta idea de
anidamiento existe una variable global @@TRANCOUNT que tiene valor 0 si
no existe ningún nivel de anidamiento, 1 si hay una transacción
anidada, 2 si estamos en el segundo nivel de anidamiento y así
sucesivamente.
La dificultad de trabajar
con transacciones anidadas está en el comportamiento que tienen
ahora las sentencias COMMIT TRAN y ROLLBACK TRAN
ROLLBACK TRAN:
Dentro de una transacción anidada esta sentencia deshace todas las
transacciones internas hasta la instrucción BEGIN TRANSACTION más
externa.
COMMIT TRAN: Dentro
de una transacción anidada esta sentencia únicamente reduce
en 1 el valor de @@TRANCOUNT, pero no finaliza ninguna transacción
ni guarda los cambios. En el caso en el que @@TRANCOUNT=1 (cuando estamos
en la última transacción) COMMIT TRAN hace que todas las
modificaciones efectuadas sobre los datos desde el inicio de la transacción
sean parte permanente de la base de datos, libera los recursos mantenidos
por la conexión y reduce @@TRANCOUNT a 0.
«
Atras | Continua
Aqui »
|