Kom igångKom igång gratis

Återlämna en bok

Du är utvecklare för Metropolitan Public Librarys hanteringssystem. Förra veckan upptäcktes ett kritiskt fel: när systemet kraschade under en bokåterlämnning markerades lånet som "returned" men boken stod kvar som "checked-out" i lagret. Det gjorde att boken var otillgänglig i flera veckor tills personalen manuellt korrigerade databasen.

När en bok återlämnas måste tre operationer antingen lyckas tillsammans eller misslyckas tillsammans:

  1. Uppdatera låneposten till statusen "returned".
  2. Ändra bokens tillgänglighet från "checked-out" till "available".
  3. Registrera en avgift om boken återlämnas för sent.

Din uppgift är att implementera korrekt transaktionskontroll för att säkerställa datakonsistens.

Den här övningen är en del av kursen

Fråga en PostgreSQL-databas i Java

Visa kurs

Övningsinstruktioner

  • Sätt autoCommit till false i början på rad 26.
  • Committa transaktionen om alla operationer lyckas på rad 59.
  • Om någon operation misslyckas, rulla tillbaka transaktionen på rad 66.

Interaktiv övning med praktiskt arbete

Testa den här övningen genom att slutföra den här exempelkoden.

public class BookReturnProcessor {
    public static void main(String[] args) {
        int loanId = 1;
        int bookId = 5;
        LocalDate dueDate = LocalDate.now().minusDays(2);
        
        try {
            boolean success = processBookReturn(loanId, bookId, dueDate);
            if (success) {
                System.out.println("Book return processed successfully.");
            } else {
                System.out.println("Book return processing failed.");
            }
        } catch (SQLException e) {
            System.err.println("Database error: " + e.getMessage());
        }
    }
    
    public static boolean processBookReturn(int loanId, int bookId, LocalDate dueDate) throws SQLException {
        Connection conn = null;
        try {
            HikariDataSource ds = HikariSetup.createDataSource();
            conn = ds.getConnection();
            
            // Start transaction by setting autoCommit to false
            conn.____(____);
            
            String updateLoanSQL = "UPDATE loans SET status = 'returned', return_date = ? WHERE loan_id = ?";
            try (PreparedStatement pstmt = conn.prepareStatement(updateLoanSQL)) {
                pstmt.setDate(1, java.sql.Date.valueOf(LocalDate.now()));
                pstmt.setInt(2, loanId);
                pstmt.executeUpdate();
            }
            
            String updateBookSQL = "UPDATE books SET status = 'available' WHERE book_id = ?";
            try (PreparedStatement pstmt = conn.prepareStatement(updateBookSQL)) {
                pstmt.setInt(1, bookId);
                pstmt.executeUpdate();
            }
            
            LocalDate today = LocalDate.now();
            if (today.isAfter(dueDate)) {
                long daysLate = ChronoUnit.DAYS.between(dueDate, today);
                double fineAmount = daysLate * 0.50;
                
                String insertFineSQL = "INSERT INTO fines (loan_id, amount, reason, date_assessed) VALUES (?, ?, ?, ?)";
                try (PreparedStatement pstmt = conn.prepareStatement(insertFineSQL)) {
                    pstmt.setInt(1, loanId);
                    pstmt.setDouble(2, fineAmount);
                    pstmt.setString(3, "Book returned " + daysLate + " days late");
                    pstmt.setDate(4, java.sql.Date.valueOf(today));
                    pstmt.executeUpdate();
                }
                
                System.out.println("Fine created: $" + fineAmount + " for loan " + loanId);
            }
            
            // Commit the transaction
            conn.____();
            
            return true;
            
        } catch (SQLException e) {
            // Roll back the transaction if an error occurs
            if (conn != null) {
                conn.____();
            }
            System.err.println("Error processing return: " + e.getMessage());
            return false;
        }
    }
}
Redigera och kör kod