ComenzarEmpieza gratis

Sábados de Club de Lectura

La Biblioteca Pública Metropolitana organiza los "Sábados de Club de Lectura", un evento muy popular en el que entre 30 y 40 socios llegan a las 10:00 para sacar sus lecturas del mes. El sistema actual procesa cada préstamo de forma individual con auto-commit activado, lo que provoca dos problemas críticos:

  1. Inconsistencia de datos: El mes pasado, el sistema se bloqueó mientras procesaba el préstamo de cuatro libros de un socio. Dos libros se registraron como prestados, pero los otros dos no, causando discrepancias en el inventario y frustración entre los usuarios.
  2. Cuello de botella de rendimiento: Procesar cada préstamo como una transacción independiente tarda entre 15 y 20 minutos, generando largas colas y enfado entre el personal de la biblioteca.

Tu misión es implementar el procesamiento por lotes con control de transacciones.

Este ejercicio forma parte del curso

Consultas a una base de datos PostgreSQL en Java

Ver curso

Instrucciones del ejercicio

  • Establece autoCommit en false para activar el control manual de transacciones en la línea 32.
  • Añade varios préstamos al lote en la línea 43.
  • Haz commit de la transacción si todas las operaciones se completan correctamente en la línea 49.

Ejercicio interactivo práctico

Prueba este ejercicio y completa el código de muestra.

public class BatchLoanProcessor {
    private static final String DB_URL = "jdbc:postgresql://localhost:5432/library_db";
    private static final String USERNAME = "postgres";
    private static final String PASSWORD = "postgres";
    
    public static void main(String[] args) {
        Object[][] loanData = {
            {1, 1, LocalDate.now(), LocalDate.now().plusDays(14), "borrowed"},
            {2, 2, LocalDate.now(), LocalDate.now().plusDays(14), "borrowed"},
            {3, 3, LocalDate.now(), LocalDate.now().plusDays(7), "borrowed"},
            {4, 1, LocalDate.now(), LocalDate.now().plusDays(14), "borrowed"}
        };
        
        try {
            boolean success = processBatchLoans(loanData);
            if (success) {
                System.out.println("All loans were processed successfully.");
            } else {
                System.out.println("Loan processing failed. Transaction was rolled back.");
            }
        } catch (SQLException e) {
            System.err.println("Database error: " + e.getMessage());
            e.printStackTrace();
        }
    }
    
    public static boolean processBatchLoans(Object[][] loanData) throws SQLException {
        String insertSQL = "INSERT INTO loans (book_id, member_id, loan_date, due_date, status) VALUES (?, ?, ?, ?, ?)";
        
        try (Connection conn = DriverManager.getConnection(DB_URL, USERNAME, PASSWORD)) {
            // Set autoCommit to false
            conn.____(____);
            
            try (PreparedStatement pstmt = conn.prepareStatement(insertSQL)) {
                for (Object[] loan : loanData) {
                    pstmt.setInt(1, (Integer) loan[0]);  
                    pstmt.setInt(2, (Integer) loan[1]);  
                    pstmt.setDate(3, java.sql.Date.valueOf((LocalDate) loan[2]));  
                    pstmt.setDate(4, java.sql.Date.valueOf((LocalDate) loan[3]));  
                    pstmt.setString(5, (String) loan[4]);  
                    
                    // Add to batch
                    pstmt.____();
                }
                
                int[] results = pstmt.executeBatch();
                                
                // Commit the transaction if all operations are successful
                conn.____();
                
                return true;
            } catch (SQLException e) {
                conn.rollback();
                
                System.err.println("Error during batch processing: " + e.getMessage());
                return false;
            }
        }
    }
}
Editar y ejecutar código