Cuando desarrollamos aplicaciones en java con base de datos debemos tener cuidado en que se cumplan un conjunto de características conocida como ACID (Atomicidad, Consistencia, Aislamiento, Durabilidad), en el caso de este post nos centraremos en la Atomicidad y Consistencia
Atomicidad: es la propiedad que asegura que la operación se ha realizado o no, y por lo tanto ante un fallo del sistema no puede quedar a medias. Se dice que una operación es atómica cuando es imposible para otra parte de un sistema encontrar pasos intermedios. Si esta operación consiste en una serie de pasos, todos ellos ocurren o ninguno. Por ejemplo, en el caso de una transacción bancaria o se ejecuta tanto el depósito como la deducción o ninguna acción es realizada. [Wikipedia]
Consistencia: Integridad. Es la propiedad que asegura que sólo se empieza aquello que se puede acabar. Por lo tanto se ejecutan aquellas operaciones que no van a romper las reglas y directrices de integridad de la base de datos. La propiedad de consistencia sostiene que cualquier transacción llevará a la base de datos desde un estado válido a otro también válido. «La Integridad de la Base de Datos nos permite asegurar que los datos son exactos y consistentes, es decir que estén siempre intactos, sean siempre los esperados y que de ninguna manera cambien ni se deformen. De esta manera podemos garantizar que la información que se presenta al usuario será siempre la misma.» [Wikipedia]
Planteando una situación para este tutorial
Si tenemos una serie de sentencias SQL INSERT por ejecutar y por un motivo XYZ 🙂 surge un error que no permite que se completen todas estas sentencias nos encontramos con el problema de que hasta el punto que se produjo el error, los INSERT se ejecutaron y se guardaron nuevos registros en la base de datos, entonces estaríamos violando los criterios de Atomicidad y de Consistencia porque no primeramente no se completo la transacción en su totalidad pero tenemos nuevos registros en la base de datos pero estos registros están incompletos.
¿Como podemos solucionar este problema?
Necesitamos
Nivel: Intermedio
Tiempo. 15 minutos
Base de datos.
Para el ejemplo de este post, utilizaremos dos tablas «miTabla» y «miOtraTabla«, su estructura es la siguiente:
-- -- Estructura de tabla para la tabla 'mitabla' -- CREATE TABLE mitabla ( DNI varchar(12) default NULL, correo varchar(32) default NULL ) ENGINE=InnoDB DEFAULT CHARSET=utf8; -- -- Estructura de tabla para la tabla 'miotratabla' -- CREATE TABLE miotratabla ( nombre varchar(20) default NULL, apellido varchar(20) default NULL, edad int(20) default NULL ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
IMPORTANTE al crear las tablas, debemos utilizar ENGINE=InnoDB y no MyISAM esto porque InnoDB tiene soporte para transacciones, bloqueo de registros y nos permite tener las características ACID garantizando la integridad de nuestras tablas.
Proyecto Netbeans
Nuestro proyecto base sera el siguiente:
package app; import java.sql.Connection; import java.sql.DriverManager; import java.sql.SQLException; /** * @web https://www.jc-mouse.net/ * @author Mouse */ public class Database { private final static String bd = "BASE_DE_DATOS"; private final static String login = "USUARIO"; private final static String password = "CONTRASEÑA"; private final static String url = "jdbc:mysql://localhost/"+bd; public static Connection getConnection(){ try{ Class.forName("com.mysql.jdbc.Driver"); Connection conn = DriverManager.getConnection(url,login,password); if (conn!=null){ System.out.println("Conectado a la base de datos ["+bd+"]"); } return conn; }catch(SQLException e){ System.err.println(e.getMessage()); }catch(ClassNotFoundException e){ System.err.println(e.getMessage()); } return null; } }
01 package app; 02 import java.sql.Connection; 03 import java.sql.PreparedStatement; 04 import java.sql.SQLException; 05 /** 06 * @web https://www.jc-mouse.net/ 07 * @author Mouse 08 */ 09 public class JNoRollback { 10 11 /** 12 * @param args the command line arguments 13 */ 14 public static void main(String[] args) { 15 16 //Obtenemos conexion a la base de datos 17 Connection connection = Database.getConnection(); 18 19 PreparedStatement stmt1=null; 20 PreparedStatement stmt2=null; 21 22 try { 23 //Se preparan las sentencias SQL 24 stmt1 = connection.prepareStatement("INSERT INTO miTabla VALUES( ?, ? );"); 25 stmt2 = connection.prepareStatement("INSERT INTO miOtraTabla VALUES( ?, ?, ? );"); 26 27 System.out.println( "Primer INSERT tabla [miTabla] " ); 28 stmt1.setString(1, "000001"); 29 stmt1.setString(2, "micorreo@mail.com"); 30 stmt1.executeUpdate(); 31 32 System.out.println( "Segundo INSERT tabla [miTabla] " ); 33 stmt1.setString(1, "000002"); 34 stmt1.setString(2, "amayuya@mail.com"); 35 stmt1.executeUpdate(); 36 37 System.out.println( "Tercer INSERT tabla [miTabla] " ); 38 stmt1.setString(1, "000003"); 39 stmt1.setString(2, "diosdado@mail.com"); 40 stmt1.executeUpdate(); 41 42 System.out.println( "Primer INSERT tabla [miOtraTabla]" ); 43 stmt2.setString(1, "Juan"); 44 stmt2.setString(2, "Perez"); 45 //stmt2.setInt(3, 99); //Tipo de dato CORRECTO INT 46 stmt2.setString(3, "Hola soy un error");//Tipo de dato INCORRECTO 47 stmt2.executeUpdate(); 48 49 } catch (SQLException ex) { 50 System.err.println("ERROR: " + ex.getMessage()); 51 }finally{ 52 System.out.println( "cierra conexion a la base de datos" ); 53 try { 54 if(stmt1!=null) stmt1.close(); 55 if(stmt2!=null) stmt2.close(); 56 if(connection!=null) connection.close(); 57 } catch (SQLException ex) { 58 System.err.println( ex.getMessage() ); 59 } 60 } 61 62 }//end:main 63 }
01 package app; 02 03 import java.sql.Connection; 04 import java.sql.PreparedStatement; 05 import java.sql.SQLException; 06 /** 07 * @web http://jc-mouse.net/ 08 * @author Mouse 09 */ 10 public class JRollback { 11 12 public static void main(String[] args) { 13 14 //Obtenemos conexion a la base de datos 15 Connection connection = Database.getConnection(); 16 17 PreparedStatement stmt1=null; 18 PreparedStatement stmt2=null; 19 20 try { 21 //se deshabilita el modo de confirmación automática 22 connection.setAutoCommit(false); 23 //Se preparan las sentencias SQL 24 stmt1 = connection.prepareStatement("INSERT INTO miTabla VALUES( ?, ? );"); 25 stmt2 = connection.prepareStatement("INSERT INTO miOtraTabla VALUES( ?, ?, ? );"); 26 27 System.out.println( "Primer INSERT tabla [miTabla] " ); 28 stmt1.setString(1, "000001"); 29 stmt1.setString(2, "micorreo@mail.com"); 30 stmt1.executeUpdate(); 31 32 System.out.println( "Segundo INSERT tabla [miTabla] " ); 33 stmt1.setString(1, "000002"); 34 stmt1.setString(2, "amayuya@mail.com"); 35 stmt1.executeUpdate(); 36 37 System.out.println( "Tercer INSERT tabla [miTabla] " ); 38 stmt1.setString(1, "000003"); 39 stmt1.setString(2, "diosdado@mail.com"); 40 stmt1.executeUpdate(); 41 42 System.out.println( "Primer INSERT tabla [miOtraTabla]" ); 43 stmt2.setString(1, "Juan"); 44 stmt2.setString(2, "Perez"); 45 //stmt2.setInt(3, 99); //Tipo de dato CORRECTO INT 46 stmt2.setString(3, "Hola soy un error");//Tipo de dato INCORRECTO 47 stmt2.executeUpdate(); 48 49 //se indica que se deben aplicar los cambios en la base de datos 50 connection.commit(); 51 52 } catch (SQLException ex) { 53 System.err.println("ERROR: " + ex.getMessage()); 54 if(connection!=null) 55 { 56 System.out.println("Rollback"); 57 try { 58 //deshace todos los cambios realizados en los datos 59 connection.rollback(); 60 } catch (SQLException ex1) { 61 System.err.println( "No se pudo deshacer" + ex1.getMessage() ); 62 } 63 } 64 }finally{ 65 System.out.println( "cierra conexion a la base de datos" ); 66 try { 67 if(stmt1!=null) stmt1.close(); 68 if(stmt2!=null) stmt2.close(); 69 if(connection!=null) connection.close(); 70 } catch (SQLException ex) { 71 System.err.println( ex.getMessage() ); 72 } 73 } 74 75 }//end:main 76 }
Yo soy yo :) JC Mouse, Soy orgullosamente boliviano soy fundador y CEO de la web jc-Mouse.net uno de las pocas web en emprendimiento y tecnología en Bolivia.
Toda la información que encuentres en este sitio es y sera completamente gratis siempre, puedes copiar, descargar y re-publicar si así lo deseas en otros blogs o sitios web, solo te pido a cambio que dejes una referencia a esta web. Esto nos ayuda a crecer y seguir aportando. Bye
Enjoy! :)
En posts anteriores hablamos sobre los metadatos y el porque son importantes en la Seguridad Informática, vimos el manej...
Notación matemática formada por una tabla cuadrada de números, u otros elementos, entre dos líneas verticales; el valor...
Los gráficos de líneas muestran una serie como un conjunto de puntos conectados mediante una línea. Los valores se repre...
¿Que es la facturación electrónica? Una factura es un documento que sirve para describir el costo de los servicios y des...
En este proyecto realizaremos una aplicación de base de datos Firebird con el lenguaje de programación de Visual Basic d...
Servicio Web Un servicio web (en inglés, Web Service o Web services) es una tecnología que utiliza un conjunto de protoc...
Los comentarios estan cerrados
Por lo general se usan transacciones a nivel base de datos y posteriormente se llaman estos a través de procedimientos a...
En este post, aprenderemos como conectar Visual Basic 6 con SQL Server, abrir una tabla, leer su contenido y mostrar est...
Lo que veremos en este post es la configuración del driver para PHP de SQL Server que ha creado Microsoft el cual permit...
Google Bard la inteligencia artificial de Google se actualiza con una mejora que entra a competir con el resto de IAs y...
Muy bueno, Mouse. Gracias por el esfuerzo de publicar lo que sabes.
Jc, un consulta como haces en JAVA para usar el begin o el start transaction de la sintaxis de mysql server?
exceletente forma de explicar el manejo de las transciones muchas gracias
Hey gracios por la explicación y el codigo me fue de gran ayuda 😀