No tienes acceso a esta clase

¡Continúa aprendiendo! Únete y comienza a potenciar tu carrera

No se trata de lo que quieres comprar, sino de quién quieres ser. Invierte en tu educación con el precio especial

Antes: $249

Currency
$209

Paga en 4 cuotas sin intereses

Paga en 4 cuotas sin intereses
Suscríbete

Termina en:

11 Días
3 Hrs
21 Min
11 Seg
Curso de Java SE: SQL y Bases de Datos

Curso de Java SE: SQL y Bases de Datos

Ana Fernanda Gutierrez Villanueva

Ana Fernanda Gutierrez Villanueva

Implementando transacciones con JDBC

16/22
Recursos
  1. Para agrupar varias sentencias en una única transacción, debes cambiar la propiedad “autocommit” de la conexión a “false”. Por defecto, esta propiedad está establecida en “true”. Al desactivar el “autocommit”, las sentencias no se ejecutarán de forma inmediata en la base de datos, lo que nos permite realizar varias operaciones en conjunto.
  2. Si todas las sentencias dentro de la transacción se completan sin errores, se realiza un “commit” al final de la transacción. El “commit” confirma los cambios y los guarda de manera permanente en la base de datos.
  3. Sin embargo, si ocurre alguna falla durante la ejecución de alguna sentencia dentro de la transacción, debes realizar un “rollback”. El “rollback” deshace todos los cambios realizados en la transacción, restaurando el estado anterior de la base de datos. Este paso se realiza dentro de un bloque catch, donde se capturan las excepciones.

Aportes 14

Preguntas 2

Ordenar por:

¿Quieres ver más aportes, preguntas y respuestas de la comunidad?

Creo que asi no este dentro de una transaccion, si no se cumple los constraints, igual no guarda

El caso de uso no me gusto tanto, porque igualmente sin haber agregado el cambio al código, no se hubiese agregado el registro. Quizas lo interesante seria un ejemplo en donde se tengan varios registros, y no se inserte ninguno si alguno tiene el mismo curp, o un ejemplo en donde el registro se hubiese insertado en la bd si no se hubiera cacheado previamente.
Yo realice la implementacion en el databaseConection, implemente una funcion para salvar la transaccion y lo llamo desde el front cuando ya tengo todas las transacciones: ![](https://static.platzi.com/media/user_upload/image-e740809f-f79e-4906-985c-2b8c699d524c.jpg)
Otra forma de controlar las transacciones es con un Stored procedure. Si todo ok -> COMMIT sino -> ROLLBACK
La clase trata sobre la implementación de transacciones utilizando JDBC en Java. Se explica cómo gestionar transacciones en una base de datos, asegurando que múltiples operaciones se realicen de manera atómica. Se muestran ejemplos prácticos de cómo establecer y manejar conexiones, realizar commits y rollbacks, y cómo agregar nuevos campos a las tablas de la base de datos para mantener la integridad de los datos. Además, se discuten patrones de diseño como DAO y Repository para una gestión de datos más estructurada.
Para crear una columna llamada `curp` en una tabla existente en MySQL, puedes usar el siguiente código en MySQL Shell: ```sql ALTER TABLE Employees ADD COLUMN curp VARCHAR(18) UNIQUE; ``` Este código añade la columna `curp` de tipo `VARCHAR` con una longitud máxima de 18 caracteres y la establece como única, lo que significa que no puede haber valores duplicados en esta columna.
Extendiendo un poco para los que creen que el ejercicio no es el adecuado. El ejemplo no esta mal. En este caso esta inconclusa la explicación. Básicamente el try donde se hace la creación de un nuevo empleado es una transacción. En ella puedes hacer múltiples peticiones usando una sola conexión. Para que puedas comprobar que el principio atomic se cumple puedes crear dos nuevos empleados en el mismo try, el cual se maneja mediante una sola conexión. En mi caso estoy creando un Usuario pero pueden replicar el ejemplo usando la clase Employee de la clase: 1. Crea dos empleados nuevos. En mi caso son usuarios. En mi base de datos tengo como valores unicos los correos que es la misma restricción del curp de la clase: `User user1 = new User();` `user1.setNickname("Architect");` `user1.setPassword("admin123");` `user1.setLogin("logead");` `user1.setEmail("[email protected]");` `user1.setNickname("DevOps");` `User user2 = new User();` `user2.setNickname("AWS");` `user2.setPassword("admin123");` `user2.setLogin("logead");` `user2.setEmail("[email protected]");` `user2.setNickname("DevOps");` `List<User> usersList;` 1. Para ver los cambios dentro del try anidado intenta crear dos usuarios con el mismo curp. En primera instancia se crea el primer Employee pero el segundo tiene un error el roleBack elimina este cambio de la Base de datos. Que es el principio de atomicidad que se busca explicar con las transacciones. 2. Puedes comprobar su funcionamiento creando dos empleados validos para que notes que el cambio se guarda. 3. Este es mi código completo, modifícalo para enviar un Employee en lugar de Usuario: `import org.example.joseFrontend.model.User;` `import org.example.joseFrontend.repository.Repository;` `import org.example.joseFrontend.repository.UserRepository;` `import org.example.joseFrontend.util.DatabaseConnection;` `import java.sql.*;` `import java.util.List;` `public class Main {` ` public static void main(String[] args) throws SQLException {` ` try(Connection myConn = DatabaseConnection.``getInstance``()){` ` if(myConn.getAutoCommit()){` ` myConn.setAutoCommit(false);` ` }` ` User user1 = new User();` ` user1.setNickname("Architect");` ` user1.setPassword("admin123");` ` user1.setLogin("logead");` ` user1.setEmail("[email protected]");` ` user1.setNickname("DevOps");` ` User user2 = new User();` ` user2.setNickname("AWS");` ` user2.setPassword("admin123");` ` user2.setLogin("logead");` ` user2.setEmail("[email protected]");` ` user2.setNickname("DevOps");` ` List<User> usersList;` ` try{` ` Repository<User> userRepository = new UserRepository(myConn);` ` System.``out``.println("--------------Antes Cambio 1----------------");` ` usersList = userRepository.findAll();` ` usersList.forEach(System.``out``::println);` ` userRepository.save(user1);` ` System.``out``.println("--------------Después Cambio 1----------------");` ` usersList = userRepository.findAll();` ` usersList.forEach(System.``out``::println);` ` System.``out``.println("--------------Antes Cambio 2----------------");` ` userRepository.save(user2);` ` System.``out``.println("--------------Después Cambio 2----------------");` ` usersList = userRepository.findAll();` ` usersList.forEach(System.``out``::println);` ` System.``out``.println("-------------------------------------");` ` myConn.commit();` ` }catch (SQLException exception){` ` myConn.rollback();` ` }` ` }` ` }` `}`
Configurando el autocommit en DatabaseConnection ```js public class DatabaseConnection { private static final String url = "jdbc:mysql://localhost:3306/project"; private static final String user = "admin"; private static final String pass = "admin123"; private static Connection connection; public static Connection getInstance() throws SQLException { if (connection == null) { connection = DriverManager.getConnection(url, user, pass); connection.setAutoCommit(false); } return connection; } } ```En Main ```js try(Connection connection = DatabaseConnection.getInstance()) { try { IRepository<Employee> employeeRepository = new EmployeeRepository(connection); System.out.println("--- Add new employee ---"); // Adding employee 1 Employee e = new Employee( "Carlangas", "Lanas Rosas", "1234567890" ); boolean done = employeeRepository.save(e); String msg = done ? "Employee created" : "Employee couldn't be created"; System.out.println("--- "+msg+" ---"); // Adding employee 2 Employee e2 = new Employee( "Papilla", "Rosales Candida", "1234567890" ); done = employeeRepository.save(e2); connection.commit(); msg = done ? "Employee created" : "Employee couldn't be created"; System.out.println("--- "+msg+" ---"); } catch (SQLException ex) { connection.rollback(); System.out.println("--- Rollback executed ---"); } } catch (SQLException e) { throw new RuntimeException(e); } ```Obtengo el siguiente resultado ```js --- Add new employee --- --- Employee created --- --- Rollback executed --- Process finished with exit code 0 ```
Hey, si no quieren borrar el paquete *view* y están usando un entorno como **Maven** o **Gradle** les recomiendo agregar lo siguiente. # Maven Dentro del **pom.xml** agreguen: ``` 1. \<project> 2. ... 3. \<build> 4. \<pluginManagement> 5. \<plugins> 6. \<plugin> 7. \<groupId>org.apache.maven.plugins\</groupId> 8. \<artifactId>maven-compiler-plugin\</artifactId> 9. \<version>3.11.0\</version> 10. \<configuration> 11. \<exclude> 12. \<exclude> 13. \*\*/view/SwingApp.java 14. \</exclude> 15. \</excludes> 16. \</configuration> 17. \</plugin> 18. \</plugins> 19. \</pluginManagement> 20. \</build> 21. ... 22. \</project> ``` # Gradle Dentro del **build.gradle** agreguen: ``` // código sourceSets { main { java { exclude '\*\*/view/SwingApp.java' } } } // más codigo ```
Para notar el funcinoamiento del rollback podemos realizar 02 consultas de tipo insert (metodo save() ). `public class ``Main {` ` ``public static void ``main(String[] args) ``throws ``SQLException {` ` ``//We create a new employee, we will use it later.` ` Employee employee03 = ``new ``Employee();` ` employee03.setFirst_name("luz");` ` employee03.setPa_surname("clarita");` ` employee03.setMa_surname("gutarra");` ` employee03.setEmail("[email protected]");` ` employee03.setSalary("50000");` ` employee03.setCurp("ROSAS1234567891R15");` ` Employee employee04 = ``new ``Employee();` ` employee04.setFirst_name("cielo");` ` employee04.setPa_surname("rosales");` ` employee04.setMa_surname("contreras");` ` employee04.setEmail("[email protected]");` ` employee04.setSalary("10000");` ` employee04.setCurp("ROSAS1234567891R15");` ` ``try``(Connection myConn = DataBaseConnection.getInstance()){` ` ``if``(myConn.getAutoCommit()){` ` myConn.setAutoCommit(``false``);` ` }` ` ``try``{` ` ``//We create an instance of EmployeeRepository` ` ``Repository<Employee> employeeRepository = ``new ``EmployeeRepository(myConn);` ` ``//Find all employees and then show them on the console.` ` ``employeeRepository.findAll().forEach(System.out::println);` ` System.out.println("*********************************************");` ` ``//We do two operations for modify data of the table` ` //insert (1)` ` ``employeeRepository.save(employee03);` ` ``//Find all employees and We see the change.` ` ``employeeRepository.findAll().forEach(System.out::println);` ` System.out.println("*********************************************");` ` ``//insert (2)` ` ``employeeRepository.save(employee04);` ` ``//Find all employees and We see the change.` ` ``employeeRepository.findAll().forEach(System.out::println);` ` } ``catch ``(SQLException e){` ` myConn.rollback();` ` ``throw new ``RuntimeException();` ` }` ` }` ` }` `}` El resultado que obtendremos sera el siguiente: ![](https://static.platzi.com/media/user_upload/rollback-355d8904-6f6a-4c4e-9fdc-54cf27f1c816.jpg) Aqui podemos ver que el primer listado es antes de realizar el insert, al segunda lista es despues de realizar el primer insert y vemos que si se anadio el registro. Al intentar realizar el segundo insert presenta un error por la duplicidad del 'corp', por lo que entra al catch( ) donde se ejecutar el 'rollback( )'. Si hacemos un SELECT desde nuestra BD o si volvemos a ejecutar el metodo findAll( ) desde el proyecto, veremos que ese registro que se inserto ya fue quitado. ![]()![](https://static.platzi.com/media/user_upload/rollback_1-e1de41fd-610e-4869-ad1c-3c90c808d4f5.jpg)
try(Connection myConn= CONECTARBD.*getInstance*()){ if(myConn.getAutoCommit()){ myConn.setAutoCommit(false); } try{ Repositorio\<PERSONA> repositorio =new CNPersona(myConn); System.*out*.println("----------- Ingreso de una nueva persona----------"); PERSONA persona=new PERSONA(); persona.setNombrePersona("Luis"); persona.setCedulaPersona("0103304531"); repositorio.Almacenar(persona); myConn.commit(); System.*out*.println("-------- IMPRIMIR TODOS LOS REGISTROS"); repositorio.LeerTodos().forEach(System.*out*::println); } catch (SQLException ex) { myConn.rollback(); throw new RuntimeException(ex); } } catch (SQLException ex) { throw new RuntimeException(ex); }
En mi caso: `public static void main(String[] args) throws SQLException { ` ` try(Connection conn= DataBaseConnection.getInstance()){` ` if(conn.getAutoCommit()){` ` conn.setAutoCommit(false);` ` }` ` try{` ` Repository<Employee> repository = new Employee_repository(conn);` ` System.out.println("....Insertar un nuevo cliente......");` ` Employee employee = new Employee();` `// employee.setFirts_name("Alejandra");` `// employee.setPa_surname("Ferrera");` `// employee.setMa_surname("Cáceres");` `// employee.setEmail("[email protected]");` `// employee.setSalary(3500F);` `// employee.setCurp("ALEJ123456741258EC");` `// repository.save(employee);` `// conn.commit();` ` ` ` employee.setFirts_name("Marco");` ` employee.setPa_surname("Nuñez");` ` employee.setMa_surname("Soto");` ` employee.setEmail("[email protected]");` ` employee.setSalary(3600F);` ` employee.setCurp("ALEJ123456741258EC");` ` repository.save(employee);` ` conn.commit();` ` }` ` catch(SQLException e){` ` conn.rollback();` ` throw new RuntimeException();` ` }`

Básicamente si creo mas empleados, como podria crear mas, deberia cambiar ese Curl? o ?

La operación la gestiono el manejador de Base de Datos porque al campo curp lo puso como UQ, no Java con el código.