CommencerCommencer gratuitement

Samedis Club de lecture

La Metropolitan Public Library organise les « Samedis Club de lecture », un événement extrêmement populaire où 30 à 40 membres arrivent à 10 h pour emprunter leurs lectures du mois. Le système actuel traite chaque prêt individuellement avec l’auto-commit activé, ce qui engendre deux problèmes critiques :

  1. Incohérence des données : le mois dernier, le système a planté pendant le traitement d’un emprunt de quatre livres par un membre. Deux livres ont été enregistrés comme empruntés, mais pas les deux autres, provoquant des écarts d’inventaire et la frustration des usagers.
  2. Goulot d’étranglement des performances : traiter chaque prêt comme une transaction distincte prend 15 à 20 minutes, entraînant de longues files d’attente et des équipes de bibliothèque mécontentes.

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

Cet exercice fait partie du cours

Interroger une base de données PostgreSQL en Java

Afficher le cours

Instructions

  • Définissez autoCommit sur 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 cet exemple de code.

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