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 :
- 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.
- 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
Instructions de l’exercice
- Réglez
autoCommitàfalsepour 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;
}
}
}
}