Implementing Automatic Order Cancellation After 30 Minutes in Spring Boot
This article explains three Spring Boot approaches—using @Scheduled tasks, RabbitMQ delayed queues, and Redis key‑expiration events—to automatically cancel orders that remain unpaid for 30 minutes, complete with code samples and configuration guidance.
Introduction
In e‑commerce and other online‑payment applications, it is common to automatically cancel an order if the user does not complete payment within a certain time window.
Solution 1: Scheduled Task
Leverage Spring Boot's @Scheduled annotation to run a periodic job that scans the database for unpaid orders older than 30 minutes and cancels them.
@Component
public class OrderCancelSchedule {
@Autowired
private OrderService orderService;
@Scheduled(cron = "0 0/1 * * * ?")
public void cancelUnpaidOrders() {
List<Order> unpaidOrders = orderService.getUnpaidOrders();
unpaidOrders.forEach(order -> {
if (order.getCreationTime().plusMinutes(30).isBefore(LocalDateTime.now())) {
orderService.cancelOrder(order.getId());
}
});
}
}Solution 2: Delayed Queue
Use a message broker such as RabbitMQ with delayed‑queue support. When an order is created, push its ID to a delayed queue set to expire after 30 minutes; the consumer processes the message and cancels the order.
@Service
public class OrderService {
@Autowired
private RabbitTemplate rabbitTemplate;
public void createOrder(Order order) {
// save order to DB
saveOrderToDB(order);
// push order ID to delayed queue
rabbitTemplate.convertAndSend("orderDelayExchange", "orderDelayKey", order.getId(), message -> {
message.getMessageProperties().setDelay(30 * 60 * 1000); // 30 minutes
return message;
});
}
}
@Component
@RabbitListener(queues = "orderDelayQueue")
public class OrderDelayConsumer {
@Autowired
private OrderService orderService;
@RabbitHandler
public void process(String orderId) {
// cancel order
orderService.cancelOrder(orderId);
}
}Solution 3: Redis Expiration Event
Store a temporary key in Redis when the order is created, set to expire after 30 minutes. Configure Redis key‑space notifications and a listener to handle the expiration event and cancel the order.
@Service
public class OrderService {
@Autowired
private StringRedisTemplate redisTemplate;
public void createOrder(Order order) {
// save order to DB
saveOrderToDB(order);
// store a key with 30‑minute TTL
redisTemplate.opsForValue().set("order:" + order.getId(), order.getId(), 30, TimeUnit.MINUTES);
}
// Called when the Redis key expires (requires notification config)
public void onOrderKeyExpired(String orderId) {
cancelOrder(orderId);
}
}To enable Redis key‑space notifications, add notify-keyspace-events "Ex" to redis.conf and configure a RedisMessageListenerContainer in Spring Boot to listen for __keyevent@*__:expired events.
Conclusion
All three solutions achieve the requirement of automatically canceling unpaid orders after 30 minutes. Choose the most suitable implementation based on business needs, system load, and operational considerations, as each approach has its own trade‑offs.
Top Architect
Top Architect focuses on sharing practical architecture knowledge, covering enterprise, system, website, large‑scale distributed, and high‑availability architectures, plus architecture adjustments using internet technologies. We welcome idea‑driven, sharing‑oriented architects to exchange and learn together.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.