COMMIT de transacciones en MySQL

Hasta ahora no había publicado nada acerca de transacciones en MySQL, pues es mucho lo que se podría hablar del tema y son muchos los ejemplos que se podrían desarrollar para entender el alcance del tópico. Sin embargo, en el afán de hacer una publicación mounstrosa, no termino haciendo nada. Por ese motivo, me limitaré a hablar algunos aspectos del tema y a realizar algunos ejemplos básicos en varias entregas. Para esta primera publicación, me enfocaré en la confirmación de transacciones.

Antes de todos, hay que aclarar que para utilizar transacciones en MySQL (versión 5.0.x), debemos utilizar el motor de almacenamiento InnoDB.

Una transacción tiene dos finales posibles, COMMIT y ROLLBACK. Por defecto, MySQL trae activado el modo autocommit, es decir, realizada una transacción (por ejemplo un INSERT, UPDATE o DELETE) el mismo es confirmado apenas es ejecutado. Para desactivar el autocommit, se puede desactivar el autocomit ejecutando el comando:
SET AUTOCOMMIT=0;

Una vez deshabilitado el autocommit, tendremos que utilizar obligatoriamente el COMMIT para confirmar o ROLLBACK para deshacer la transacción.

Si se quiere deshabilitar el autocommit para una serie de comandos, lo ideal es utilizar START   TRANSACTION (sin necesidad de setear el AUTOCOMMIT en 0).

Al ejecutar una transacción, el motor de base de datos nos garantizará la atomicidad, consistencia, aislamiento y durabilidad (ACID) de la transacción (o conjunto de comandos) que se utilice.

Veremos un ejemplo completo, extraído del articulo fuente de esta publicación, donde utilizaremos START TRANSACTION (no es necesario AUTOCOMMIT en 0)

CREATE TABLE `departamentos` (
`CODIGO` INTEGER(11) NOT NULL DEFAULT ’0′,
`NOMBRE` VARCHAR(100),
`PRESUPUESTO` INTEGER(11) DEFAULT NULL,
PRIMARY KEY (`CODIGO`)
)ENGINE=InnoDB

Ahora, insertaremos registros de la tabla departamentos_externos a departamentos mediante una transacción:

START TRANSACTION;
SELECT @A := presupuesto
FROM departamentos_externos
WHERE codigo =11;
INSERT INTO departamentos( codigo, nombre, presupuesto )
VALUES ( 11, ‘Department test’, @A );
COMMIT;

En el ejemplo anterior se guardo el presupuesto del departamento externo 11 en la variable @A y luego fue asignado al presupuesto en la tabla departamentos.

Otro ejemplo:
START TRANSACTION;
SELECT @A := presupuesto, @B := codigo, @C := nombre
FROM departamentos_externos
WHERE codigo=33;
INSERT INTO departamentos( codigodep, nombredep, presupuesto ) VALUES (@B , @C , @A );
COMMIT ;

Otro ejemplo más:
START TRANSACTION;
SELECT @A:=PRESUPUESTO FROM departamentos_externos WHERE codigo=11;
UPDATE departamentos SET PRESUPUESTO = PRESUPUESTO + @A WHERE codigo=33;
COMMIT;

Al realizar una transacción SQL hay que tener en cuenta que apenas se realice un INSERT, UPDATE o DELETE se genera un bloqueo sobre la tabla y que otros clientes no pueden acceder para escribir esta tabla. Otros clientes podrán realizar SELECTs sobre la tabla, pero no podrán ver los datos del primer cliente hasta que los mismos sean confirmados. Prometo pronto, tratar con más detalle el tema de bloqueos, específicamente el procesamiento concurrente de transacciones.

Vía: Geek Linux

13 comentario en este artículoDeje el suyo
  1. y el roolback en que momento se utiliza? :(

  2. GRACIAS FUE MUY UTIL PARA ENTREGAR MI INVESTIGACION Y POR CIERTO FUE DIFICIL DE ENCOTRARLO!!!!!!!!!!!!!!!!!!!!!!!!!

  3. repondiendo a noe Romeo:

    usando el ejemplo del amigo de arriba.

    START TRANSACTION;
    SELECT @A:=PRESUPUESTO FROM departamentos_externos WHERE codigo=11;
    UPDATE departamentos SET PRESUPUESTO = PRESUPUESTO + @A WHERE codigo=33;
    INSERT INTO departamentos_externos(RESUPUESTO) VALUES(‘valor’) WHERE codigo=11;

    COMMIT; // para aceptar la transaccion
    ó
    ROLLBACK;//si quieres cancelar la transaccion

    Nota: una ves q has realizado una o varias consultas (SELECT,UPDATE; DELETE,INSERT…) tienes dos opciones, aceptar la transaccion, o cancelar la transaccion, para aceptar la transaccion y los datos sean ingresados, actualizados, borrados( depende la sentencia que ayas usado) a la base de datos, utilizas COMMIT.
    Para cancelar la transaccion (osea cancelar todas las sentencias realizadas) utilizas ROLLBACK.

    una ves utilizada la sentencia COMMIT ya no puedes usar ROLLBACK.

    espero me haya dado a entender…

  4. Aportando un poco mas a la pregunta de noe a pesar de q lleva mas de 1 años, el rollback se colocaria en alguna instruccion en caso de q se produsca algun error, por ejemplo puedes hacer varios insert y en alguno de los query sea errado se produsca un error, entonces seria convenienete ejecutar un rollback para cancelar todos los insert,

    Bueno se q no soy bueno explicando pero espero me entiendan ;-)

  5. opino lo mismo que anRoswell, si se ocurriese algun error, como hago el rollback??

  6. Al igual que wa, tengo la duda de cómo hacer el rollback en caso de error. Muchas gracias.

  7. Hola a todos. en respuesta a las últimas preguntas: que ocurra un error en el query ejecutado dentro de la transaccion, no implica que la base de datos quedó inactiva o que ya no podrás ejecutar ningún query, sino que, sólo ese query resultó fallido por un motivo que se desconoce desde afuera del motor de BD. Por lo cual:
    1) inciar transaccion.
    2) ejecutar querys que modifican la base. (insert, delete y update)
    3) controlar el resultado de los querys:
    3) = OK => ejecutar commit
    3) = FAIL => ejecutar rollback

    espero que les sirva.
    un saludo a todos.

  8. Hola! Realice el sig Procedimiento,ingreso datos donde falla la segunda sentencia de insert, lo que quiero saber es como hacer para que se regresen los datos como estaban de la primera sentencia si la segunda falla…

    PROCEDURE `Registra`(IN `NOMBRE` varchar(150),IN `DOM` varchar(150),IN `EST` int (2),IN `MUN` int(2),IN `INST` int(2),
    IN `FECHA` varchar(100),IN `TEL` varchar(30),IN FAX varchar(25),IN `CORREO` varchar(30),IN `ESTATUS` int(2), IN `OBSERVA` varchar(250))
    BEGIN
    SET AUTOCOMMIT = 0;
    START TRANSACTION WITH CONSISTENT SNAPSHOT;
    SELECT @S:= MAX(USUARIO) FROM USUARIOS ;
    SELECT @SO:= SUBSTRING(@S,CHARACTER_LENGTH(@S)-2,CHARACTER_LENGTH(@S)) + 1 ;
    SELECT @NVOCBE:= IF(CHARACTER_LENGTH(@SO)+2 =4,CONCAT (‘TV’,’0′,@SO),CONCAT(‘TV’,@SO)) ;
    SELECT @NVOPASS:= IF(CHARACTER_LENGTH(@SO)+2 =4,CONCAT (‘tele’,’0′,@SO),CONCAT(‘tele’,@SO)) ;
    INSERT INTO USUARIOS VALUES (0,NOMBRE,@NVOCBE,@NVOPASS,ESTATUS,3);
    sELECT @IDUSER:=IDUSUARIO FROM USUARIOS WHERE USUARIO = @NVOCBE;
    INSERT INTO TELEAULAS VALUES(@IDUSER,DOM,EST,MUN ,INST,FECHA,TEL,FAX,CORREO,OBSERVA);
    COMMIT;
    END;

  9. hola que tal …me parece interesante pero en muy basico… seria bueno que publiques sobre transacccion con manejos de errores y el uso del rollback en estos casos…
    saludos cordiales…

  10. Exacto lo que queremos es como se reconoce para la ejecucion del rollback,o el commit.
    Ya sabemos q es lo que pasa cuando se usa.
    en q circunstancias se ejecuta porque no vemos la falla del procedimineto pero debe estar el rolback y cuando correcto de forma automatica ejecutarse el comint.

  11. hola quisiera saber si me pueden orientar de como se realiza una transaccion que inserte un registro en una tabla que sellama boleta pero siempre y cuando el numero de control de una alumno exista

  12. Estos ejemplos estan muy buenos, pero el resultado de ejecutar estos procedimientos almacenados es que siempre me regresa el primer select, y yo quiero que me regrese un select que ejecuto despues del update o del insert, en MS SQL la funcion que se usa es la SET NOCOUNT ON para deshabilitar el resultado de la consulta y cuando ya se desea regresar el resultado de alguna instruccion se pone SET NOCOUNT OFF, como se hace esto en MySql?

  13. CREATE TABLE #T1 (ID INT, NOMBRE VARCHAR(50))
    GO

    CREATE TABLE #T2 (ID INT, FECHA DATETIME NOT NULL)
    GO

    BEGIN TRY

    BEGIN TRAN

    INSERT INTO #T1 VALUES (1,’CONDUIT’)
    INSERT INTO #T1 VALUES (1,GETDATE())

    COMMIT TRAN
    END TRY

    BEGIN CATCH
    ROLLBACK TRAN
    SELECT @@ERROR
    END CATCH

    En el ejemplo básicamente hacemos dos insert y si hay algún error entramos en la sección del Catch y lo primero que hacemos es el rollback para luego mostrar el error.

    Este es un simple ejemplo donde si no hay problemas se harán los dos insert y el commit los confirmara y de haber un error en algún insert se hará Rollback.

Deje su comentario

Por favor, ingrese su nombre

Por favor, ingrese un correo-e válido

Por favor, ingrese su mensaje

luauf.com 2014

WordPress