Está en la página 1de 7

QUE ES UNA TRANSACCIN EN SQL?

Una transaccin es un conjunto secuencial de cambios a una base de datos. Las


transacciones se emplean como mecanismo de peticin para bases de datos de
multiusuarios (concurrencia).
Una transaccin es una unidad de trabajo compuesta por diversas tareas, cuyo
resultado final debe ser que se ejecuten todas o ninguna de ellas.
TRANSACCIONES IMPLCITAS Y EXPLICITAS
Para agrupar varias sentencias Transact SQL en una nica transaccin, disponemos
de los siguientes mtodos:

Transacciones explcitas

Cada transaccin se inicia explcitamente con la instruccin BEGIN TRANSACTION y


se termina explcitamente con una instruccin COMMIT o ROLLBACK.

Transacciones implcitas

Se inicia automticamente una nueva transaccin cuando se ejecuta una instruccin


que realiza modificaciones en los datos, pero cada transaccin se completa
explcitamente con una instruccin COMMIT o ROLLBACK.
CMO DEFINIR TRANSACCIONES
Por regla general en los gestores de datos relacionales modernos disponemos de tres
tipos de transacciones segn la forma de iniciarlas:

De confirmacin automtica: el gestor de datos inicia una transaccin


automticamente por cada operacin que actualice datos. De este modo
mantiene siempre la consistencia de la base de datos, aunque puede generar
bloqueos.
Implcitas: cuando el gestor de datos comienza una transaccin
automticamente cada vez que se produce una actualizacin de datos, pero el
que dicha transaccin se confirme o se deshaga, lo debe indicar el
programador.
Explcitas: son las que iniciamos nosotros "a mano" mediante instrucciones SQ.
somos nosotros, los programadores, los que indicamos qu operacio0nes va a
abarcar.

Una transaccin explcita se define de manera general con una instruccin que marca
su inicio, y dos posibles instrucciones que marcan su final en funcin de si debe tener
xito o debe fracasar en bloque.
Transacciones anidadas.
Podemos anidar varias transacciones. Cuando anidamos varias transacciones la
instruccin COMMIT afectar a la ltima transaccin abierta, pero ROLLBACK afectar
a todas las transacciones abiertas.

Un hecho a tener en cuenta, es que, si hacemos ROLLBACK de la transaccin


superior se desharan tambin los cambios de todas las transacciones internas, aunque
hayamos realizado COMMIT de ellas.
Puntos de recuperacion (SavePoint).
Los puntos de recuperacin (SavePoints) permiten manejar las transacciones por
pasos, pudiendo hacer rollbacks hasta un punto marcado por el savepoint y no por
toda la transaccin.
Propiedades ACID
Una transaccin, para cumplir con su propsito y protegernos de todos los problemas
que hemos visto, debe presentar las siguientes caractersticas:

Atomicidad: las operaciones que componen una transaccin deben


considerarse como una sola.
Consistencia: una operacin nunca deber dejar datos inconsistentes.
Aislamiento: los datos "sucios" deben estar aislados, y evitar que los usuarios
utilicen informacin que an no est confirmada o validada. (por ejemplo:
sigue siendo vlido el saldo mientras realizo la operacin?)
Durabilidad: una vez completada la transaccin los datos actualizados ya sern
permanentes y confirmados.

A estas propiedades se las suele conocer como propiedades ACID (de sus siglas en
ingls: Atomicity, Consistency, Isolation yDurability).
CONTROL DE UNA TRANSACCIN
Para dirigir el flujo de una transaccin con efectividad y mantener sus propiedades,
existen las siguientes sentencias en SQL. La sintaxis y etiqueta dependen de cada
gestor de bases de datos:

COMMIT : guarda los cambios.


ROLLBACK: deshace los cambios.
SAVEPOINT: crea un punto de restauracin dentro de un conjunto de
transacciones para luego deshacer los cambios si es necesario.

TRANSACCIONES EN SQL SERVER


En SQL Server las instrucciones equivalentes a las genricas que acabamos de ver
son:

BEGIN TRANSACTION o BEGIN TRAN: marca el inicio de una transaccin.


TRAN es un sinnimo de TRANSACTION y se suele usar ms a menudo por
abreviar.
ROLLBACK TRANSATION o ROLLBACK TRAN: fuerza que se deshaga la
transaccin en caso de haber un problema o querer abandonarla. Cierra la
transaccin.
COMMIT TRANSACTION O COMMIT TRAN: confirma el conjunto de
operaciones convirtiendo los datos en definitivos. Marca el xito de la operacin
de bloque y cierra la transaccin.

Los niveles de aislamiento que nos ofrece SQL Server son:

SERIALIZABLE: No se permitir a otras transacciones la insercin,


actualizacin o borrado de datos utilizados por nuestra transaccin. Los
bloquea mientras dura la misma.
REPEATABLE READ: Garantiza que los datos ledos no podrn ser cambiados
por otras transacciones, durante esa transaccin.
READ COMMITED: Una transaccin no podr ver los cambios de otras
conexiones hasta que no hayan sido confirmados o descartados.
READ UNCOMMITTED: No afectan los bloqueos producidos por otras
conexiones a la lectura de datos.
SNAPSHOT: Los datos seleccionados en la transaccin se vern tal y como
estaban al comienzo de la transaccin, y no se tendrn en cuenta las
actualizaciones que hayan sufrido por la ejecucin de otras transacciones
simultneas.

DECLARE @importe DECIMAL(18,2),


@CuentaOrigen VARCHAR(12),
@CuentaDestino VARCHAR(12)
/* Asignamos el importe de la transferencia

* y las cuentas de origen y destino


*/
SET @importe = 50
SET @CuentaOrigen = '200700000001'
SET @CuentaDestino = '200700000002'
/* Descontamos el importe de la cuenta origen */
UPDATE CUENTAS
SET SALDO = SALDO - @importe
WHERE NUMCUENTA = @CuentaOrigen
/* Registramos el movimiento */
INSERT INTO MOVIMIENTOS
(IDCUENTA, SALDO_ANTERIOR, SALDO_POSTERIOR, IMPORTE, FXMOVIMIENTO)
SELECT
IDCUENTA, SALDO + @importe, SALDO, @importe, getdate()
FROM CUENTAS
WHERE NUMCUENTA = @CuentaOrigen
/* Incrementamos el importe de la cuenta destino */
UPDATE CUENTAS
SET SALDO = SALDO + @importe
WHERE NUMCUENTA = @CuentaDestino
/* Registramos el movimiento */
INSERT INTO MOVIMIENTOS
(IDCUENTA, SALDO_ANTERIOR, SALDO_POSTERIOR, IMPORTE, FXMOVIMIENTO)
SELECT
IDCUENTA, SALDO - @importe, SALDO, @importe, getdate()
FROM CUENTAS
WHERE NUMCUENTA = @CuentaDestino
Esta forma de actuar seria erronea, ya que cada instruccin se ejecutaria y
confirmara de forma independiente, por lo que un error dejara los datos erroneos
en la base de datos ( y ese es el peor error que nos podemos encontrar! )

Transacciones implicitas y explicitas


Para activar-desactivar el modo de transacciones implicitas debemos ejecutar la
siguiente instruccin.

--Activamos el modo de transacciones implicitas


SET IMPLICIT_TRANSACTIONS ON
--Desactivamos el modo de transacciones implicitas
SET IMPLICIT_TRANSACTIONS OFF

Cuando la opcin ANSI_DEFAULTS est establecida


en ON, IMPLICIT_TRANSACTIONS tambin se establece en ON.

El siguiente ejemplo muestra el script anterior haciendo uso de transacciones


explicitas.
DECLARE @importe DECIMAL(18,2),
@CuentaOrigen VARCHAR(12),
@CuentaDestino VARCHAR(12)
/* Asignamos el importe de la transferencia
* y las cuentas de origen y destino
*/
SET @importe = 50
SET @CuentaOrigen = '200700000002'
SET @CuentaDestino = '200700000001'
BEGIN TRANSACTION -- O solo BEGIN TRAN
BEGIN TRY
/* Descontamos el importe de la cuenta origen */
UPDATE CUENTAS
SET SALDO = SALDO - @importe
WHERE NUMCUENTA = @CuentaOrigen
/* Registramos el movimiento */
INSERT INTO MOVIMIENTOS
(IDCUENTA, SALDO_ANTERIOR, SALDO_POSTERIOR,
IMPORTE, FXMOVIMIENTO)
SELECT
IDCUENTA, SALDO + @importe, SALDO, @importe, getdate()
FROM CUENTAS
WHERE NUMCUENTA = @CuentaOrigen
/* Incrementamos el importe de la cuenta destino */
UPDATE CUENTAS
SET SALDO = SALDO + @importe
WHERE NUMCUENTA = @CuentaDestino
/* Registramos el movimiento */
INSERT INTO MOVIMIENTOS
(IDCUENTA, SALDO_ANTERIOR, SALDO_POSTERIOR,
IMPORTE, FXMOVIMIENTO)
SELECT
IDCUENTA, SALDO - @importe, SALDO, @importe, getdate()
FROM CUENTAS
WHERE NUMCUENTA = @CuentaDestino
/* Confirmamos la transaccion*/
COMMIT TRANSACTION -- O solo COMMIT
END TRY
BEGIN CATCH
/* Hay un error, deshacemos los cambios*/
ROLLBACK TRANSACTION -- O solo ROLLBACK
PRINT 'Se ha producido un error!'
END CATCH

El siguiente ejemplo muestra el mismo script con transacciones implicitas.


SET IMPLICIT_TRANSACTIONS ON

DECLARE @importe DECIMAL(18,2),


@CuentaOrigen VARCHAR(12),
@CuentaDestino VARCHAR(12)
/* Asignamos el importe de la transferencia
* y las cuentas de origen y destino
*/
SET @importe = 50
SET @CuentaOrigen = '200700000002'
SET @CuentaDestino = '200700000001'
BEGIN TRY
/* Descontamos el importe de la cuenta origen */
UPDATE CUENTAS
SET SALDO = SALDO - @importe
WHERE NUMCUENTA = @CuentaOrigen
/* Registramos el movimiento */
INSERT INTO MOVIMIENTOS
(IDCUENTA, SALDO_ANTERIOR, SALDO_POSTERIOR,
IMPORTE, FXMOVIMIENTO)
SELECT
IDCUENTA, SALDO + @importe, SALDO, @importe, getdate()
FROM CUENTAS
WHERE NUMCUENTA = @CuentaOrigen
/* Incrementamos el importe de la cuenta destino */
UPDATE CUENTAS
SET SALDO = SALDO + @importe
WHERE NUMCUENTA = @CuentaDestino
/* Registramos el movimiento */
INSERT INTO MOVIMIENTOS
(IDCUENTA, SALDO_ANTERIOR, SALDO_POSTERIOR,
IMPORTE, FXMOVIMIENTO)
SELECT
IDCUENTA, SALDO - @importe, SALDO, @importe, getdate()
FROM CUENTAS
WHERE NUMCUENTA = @CuentaDestino
/* Confirmamos la transaccion*/
COMMIT TRANSACTION -- O solo COMMIT
END TRY
BEGIN CATCH
/* Hay un error, deshacemos los cambios*/
ROLLBACK TRANSACTION -- O solo ROLLBACK
PRINT 'Se ha producido un error!'
END CATCH

La transaccin sigue activa hasta que emita una


instruccin COMMIT o ROLLBACK. Una vez que la primera transaccin se ha
confirmado o revertido, se inicia automticamente una nueva transaccin la
siguiente vez que la conexin ejecuta una instruccion para modificar datos.
La conexin contina generando transacciones implcitas hasta que se desactiva
el modo de transacciones implcitas.
Podemos verificar el nmero de transacciones activas a travs de
@@TRANCOUNT.

SET IMPLICIT_TRANSACTIONS ON

BEGIN TRY
UPDATE CUENTAS SET FXALTA = FXALTA - 1
PRINT @@TRANCOUNT
COMMIT
END TRY
BEGIN CATCH
ROLLBACK
PRINT 'Error'
END CATCH

Transacciones anidadas.
BEGIN TRAN
UPDATE EMPLEADOS
SET NOMBRE = 'Devjoker'
WHERE ID=101
BEGIN TRAN
UPDATE EMPLEADOS
SET APELLIDO1 = 'Devjoker.COM'
WHERE ID=101
-- Este COMMIT solo afecta a la segunda transaccion.
COMMIT
-- Este ROLLBACK afecta a las dos transacciones.
ROLLBACK

Una consideracin a tener en cuanta cuando trabajamos con transacciones


anidadas es la posibilidad de utilizar puntos de guardado o SAVEPOINTs.

Puntos de recuperacion (SavePoint).


BEGIN TRAN
UPDATE EMPLEADOS
SET NOMBRE = 'Devjoker'
WHERE ID=101
UPDATE EMPLEADOS
SET APELLIDO1 = 'Devjoker.COM'
WHERE ID=101
SAVE TRANSACTION P1 -- Guardamos la transaccion (Savepoint)
UPDATE EMPLEADOS
SET APELLIDO1 = 'Otra cosa!'
WHERE ID=101
-- Este ROLLBACK afecta solo a las instrucciones
-- posteriores al savepoint P1.
ROLLBACK TRANSACTION P1
-- Confirmamos la transaccion
COMMIT

También podría gustarte