Handling Failures with Compensating Transactions in Sagas
Provide an example of handling failures in a saga in JavaScript with compensating transactions for a booking system where a failure in booking a hotel leads to canceling the flight reservation.
class BookingSaga {
constructor(bookingService, flightService) {
this.bookingService = bookingService;
this.flightService = flightService;
}
async bookTrip(userId, tripDetails) {
try {
// Step 1: Reserve a flight
const flight = await this.flightService.reserveFlight(tripDetails.flight);
console.log('Flight reserved', flight);
// Step 2: Book a hotel - If fails, compensate previous steps
const hotel = await this.bookingService.bookHotel(tripDetails.hotel);
console.log('Hotel booked', hotel);
// If both steps are successful, return booking details
return { flight, hotel };
} catch (error) {
console.error('Booking failed', error);
// Compensating transaction for flight reservation
await this.flightService.cancelFlight(tripDetails.flight);
console.log('Flight reservation canceled');
throw error; // rethrow the error after compensation
}
}
}
This JavaScript class 'BookingSaga' handles a travel booking process as a saga. It tries to reserve a flight and book a hotel sequentially. If the hotel booking fails, it compensates by canceling the already reserved flight, ensuring system consistency despite the partial failure.