CommencezCommencez gratuitement

Samedis Club de lecture

La Bibliothèque publique métropolitaine organise les « Samedis Club de lecture », un événement très populaire où 30 à 40 membres arrivent à 10 h pour emprunter leurs sélections mensuelles. Le système actuel traite chaque prêt individuellement avec l'auto-validation activée, ce qui entraîne deux problèmes majeurs :

  1. Incohérence des données : le mois dernier, le système s'est écrasé pendant le traitement de l'emprunt de quatre livres par un membre. Deux livres ont été enregistrés comme prêtés, mais pas les deux autres, ce qui a causé des écarts d'inventaire et de la frustration chez les usagers.
  2. Goulot d'étranglement de performance : traiter chaque prêt comme une transaction distincte dans la base de données prend 15 à 20 minutes, ce qui provoque de longues files et mécontente le personnel de la bibliothèque.

Votre mission est de mettre en place un traitement par lots avec contrôle des transactions.

Cette activité fait partie du cours

Interroger une base de données PostgreSQL en Java

Voir le cours

Instructions de l’exercice

  • Réglez autoCommit à false pour activer le contrôle manuel des transactions à la ligne 32.
  • Ajoutez plusieurs prêts au lot à la ligne 43.
  • Validez la transaction si toutes les opérations réussissent à la ligne 49.

Exercice interactif pratique

Essayez cet exercice en complétant ce code d’exemple.

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;
            }
        }
    }
}
Modifier et exécuter le code