Aan de slagGa gratis aan de slag

Boekenclub op zaterdag

De Metropolitan Public Library organiseert "Book Club Saturdays", een razend populair evenement waarbij 30–40 leden om 10.00 uur binnenkomen om hun maandelijkse keuze te lenen. Het huidige systeem verwerkt elke lening apart met auto-commit ingeschakeld, wat twee kritieke problemen veroorzaakt:

  1. Datainconsistentie: Vorige maand crashte het systeem tijdens het verwerken van de vier boeken van een lid. Twee boeken werden geregistreerd als uitgeleend, maar de andere twee niet, wat leidde tot voorraadverschillen en gefrustreerde bezoekers.
  2. Prestatieknelpunt: Elke lening als aparte databasetransactie verwerken kost 15–20 minuten, wat tot lange rijen en ontevreden bibliotheekmedewerkers leidt.

Jouw missie is om batchverwerking met transactieregeling te implementeren.

Deze oefening maakt deel uit van de cursus

Query's uitvoeren op een PostgreSQL-database in Java

Cursus bekijken

Oefeninstructies

  • Zet autoCommit op false om handmatige transactieregeling in te schakelen op regel 32.
  • Voeg meerdere leningen toe aan de batch op regel 43.
  • Commit de transactie als alle bewerkingen slagen op regel 49.

Praktische interactieve oefening

Probeer deze oefening eens door deze voorbeeldcode in te vullen.

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;
            }
        }
    }
}
Code bewerken en uitvoeren