none
Cómo ejecutar varias sentencias SQL en mySQL desde aplicación ASP.NET con COMMIT Y ROLLBACK?

    Pregunta

  • Tengo una caja de texto en la que introduzco varias sentencias SQL separadas por ";".

    Todas las sentencias deben ejecutarse en la BD (mySQL) y si alguna produce algún error debe deshacer las anteriores (ROLLBACK) y si no da ningún fallo guardar los cambios (COMMIT).

    ¿Cómo sería la estructura en MySQL para poder ejecutar dicha funcionalidad?

    Podría enviarle al método SqlCommand.ExecuteNonQuery toda la sentencia mySQL incluido el rollback y commit?

    es decir algo como esto:

    START TRANSACTION;
    select 1;
    select 2;
    ...
    COMMIT
    ROLLBACK

    Si lo ejecuto con un SqlCommand.ExecuteNonQuery me devolvería la fila en la que ha fallado la transacción en el caso de fallar?

    gracias por su ayuda.

    martes, 13 de agosto de 2013 11:00

Respuestas

  • Aqui te dejo un ejemplo un poco feo que me acabo de inventar y no se si funciona por que lo he echo con notepad, espero que puedas ver un poco la idea.

    try
    {
        conexion = Tuconexion();
        cmd = conexion.CreateCommand();
        transaccion = conexion.BeginTransaction();
        cmd.Transaction = transaccion;
        //Comandos a ejecutar...	
        //Ejemplo 1:
        //delete (loquesea y solo queremos que borre una fila)
        if (cmd.ExecuteNonQuery(delete) == 1)
           transaccion.Commit();
        else 
           transaccion.Rollback();
        //Ejemplo 2: 
        //Insertamos un registro
        if(cmd.ExecuteNonQuery(insercion) ==1) 
           transaccion.commit();
        else
           transaccion.Rollback();
    }
    catch (Exception ex)
    {
        transaccion.Rollback();
    }
    finally
    {
        if (conexion != null) conexion.Close();
    }

    Ademas, creo que mysql soporta Savepoints que quizá te sean de utilidad sobre todo en procedimientos almacenados. (otra cosa que debes mirar es eso usar procedimientos almacenados para hacer estos labores).

    Para saber donde fallo o bien en los if que están o si fue por un pete "gordo" en el catch capturas la excepcion y la propiedad ex.ToString() te dará mas información.

    Saludos.


    • Editado Jnavero martes, 13 de agosto de 2013 11:50 edicion
    • Marcado como respuesta _PSK_ lunes, 19 de agosto de 2013 6:21
    martes, 13 de agosto de 2013 11:49

Todas las respuestas

  • Buenas, en teoria, si la estructura es algo así como la describes, solo que debes cotnrolar que executenonquery retorne un numero positivo para saber que ha ido correctamente, si no es así hay que hacerle el rollback por que ha fallado.

    Tambien te recomiendo una estructura de tipo try y catch y si falla por cualquier cosa en el catch meter tambien el rollback (nunca se sabe).

    Por ultimo indicarte que para sentencias select, es una tonteria usar transacciones, esto se utiliza para sentencias de modificacion, insercion o borrado. Piensa que el select si no va bien no retorna datos pero, nunca se modifica la base de datos.

    Un saludo.

    martes, 13 de agosto de 2013 11:23
  • Gracias por tu respuesta, sí los select los puse en el ejemplo pero las sentencias seran INSERT, UPDATE y DELETE por ello el tema del ROLLBACK.

    lo que no tengo muy claro es cual es la estructura del SQL, es decir cómo indicar que si falla haga el rollback y sino el COMMIT.

    He leido que hay que añadir la instrucción: set xact_abort, en SQL yo usaba @@ERROR pero mysql no lo reconoce.

    Puede adjuntarme un trozo de código que use el try catch en el sql como me indicas?

    Y la otra duda es cómo sé que línea a fallado? ncesitaría saber la sentencia SQL que ha producido el error, sería posible?

    martes, 13 de agosto de 2013 11:32
  • Aqui te dejo un ejemplo un poco feo que me acabo de inventar y no se si funciona por que lo he echo con notepad, espero que puedas ver un poco la idea.

    try
    {
        conexion = Tuconexion();
        cmd = conexion.CreateCommand();
        transaccion = conexion.BeginTransaction();
        cmd.Transaction = transaccion;
        //Comandos a ejecutar...	
        //Ejemplo 1:
        //delete (loquesea y solo queremos que borre una fila)
        if (cmd.ExecuteNonQuery(delete) == 1)
           transaccion.Commit();
        else 
           transaccion.Rollback();
        //Ejemplo 2: 
        //Insertamos un registro
        if(cmd.ExecuteNonQuery(insercion) ==1) 
           transaccion.commit();
        else
           transaccion.Rollback();
    }
    catch (Exception ex)
    {
        transaccion.Rollback();
    }
    finally
    {
        if (conexion != null) conexion.Close();
    }

    Ademas, creo que mysql soporta Savepoints que quizá te sean de utilidad sobre todo en procedimientos almacenados. (otra cosa que debes mirar es eso usar procedimientos almacenados para hacer estos labores).

    Para saber donde fallo o bien en los if que están o si fue por un pete "gordo" en el catch capturas la excepcion y la propiedad ex.ToString() te dará mas información.

    Saludos.


    • Editado Jnavero martes, 13 de agosto de 2013 11:50 edicion
    • Marcado como respuesta _PSK_ lunes, 19 de agosto de 2013 6:21
    martes, 13 de agosto de 2013 11:49
  • Muchas gracias me sirvió de mucho tú ayuda, siguiendo tu código logré implementar lo que necesitaba.

    Gracias!

    un saludo.

    miércoles, 14 de agosto de 2013 11:56
  • Me alegro, haberte sido de ayuda :-):-)

    Recuerda marcar la pregunta como respondida para cerrarla

    Saludos

    jueves, 15 de agosto de 2013 14:36