Book Club Saturdays
Die Metropolitan Public Library veranstaltet die „Book Club Saturdays“, ein äußerst beliebtes Event, bei dem zwischen 30 und 40 Mitglieder um 10 Uhr ihre monatlichen Auswahlen ausleihen. Das aktuelle System verarbeitet jede Ausleihe einzeln mit aktiviertem Auto-Commit und verursacht damit zwei kritische Probleme:
- Dateninkonsistenz: Letzten Monat ist das System während der Verarbeitung der Ausleihe von vier Büchern eines Mitglieds abgestürzt. Zwei Bücher wurden als ausgeliehen verzeichnet, die anderen beiden nicht – das führt zu Bestandsabweichungen und frustrierten Besucherinnen und Besuchern.
- Leistungsengpass: Jede Ausleihe als separate Datenbanktransaktion zu verarbeiten, dauert 15–20 Minuten und sorgt für lange Warteschlangen und unzufriedenes Bibliothekspersonal.
Deine Aufgabe ist es, Batch-Verarbeitung mit Transaktionskontrolle zu implementieren.
Diese Übung ist Teil des Kurses
Abfragen einer PostgreSQL-Datenbank in Java
Anleitung zur Übung
- Setze
autoCommitauffalse, um die manuelle Transaktionskontrolle zu aktivieren, in Zeile 32. - Füge mehrere Ausleihen in Zeile 43 zum Batch hinzu.
- Bestätige die Transaktion, wenn alle Operationen erfolgreich waren, in Zeile 49.
Interaktive Übung
Vervollständige den Beispielcode, um diese Übung erfolgreich abzuschließen.
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;
}
}
}
}