前言
在電商、外賣、預約服務等場景中,訂單超時自動取消是一個常見的業務需求。這一功能不僅提高了系統的自動化程度,還為使用者提供了更好的體驗。需求如下:
TODO
如果使用者在生成訂單後一定時間未支付,則系統自動取消訂單。
接下來就用 SpringBoot 實現訂單超時未支付自動取消的幾種方案,並提供相應的程式碼示例。
技術選型
基於產品需求,我們首先會思考可行性的解決方案。
-
Spring Task: Spring Boot內建了任務排程功能,可以很方便地實現定時任務。我們可以利用
@Scheduled
註解來定義一個定時任務,定期檢查訂單狀態並執行相應的取消操作。 -
非同步處理:對於訂單超時這種非即時性的操作,我們可以使用非同步處理來提高系統的響應速度。Spring Boot 支援多種非同步處理方式,如使用
@Async
註解、配置執行緒池等。
方案一:使用定時任務
實現步驟
- 定義訂單實體:在資料庫中,我們需要一個訂單表來儲存訂單資訊,包括訂單狀態、建立時間等。
@Entity
public class Order {
@Id
private Long id;
private String userId;
private OrderStatus status; // 訂單狀態
private Date createTime; // 訂單建立時間
// 其他欄位和getter、setter方法
}
- 建立定時任務:使用Spring Task建立一個定時任務,定期檢查訂單狀態。
@Component
public class OrderTimeoutTask {
@Autowired
private OrderService orderService;
@Scheduled(fixedRate = 5000) // 每5秒執行一次
public void checkOrderTimeout() {
List<Order> timeoutOrders = orderService.findTimeoutOrders();
timeoutOrders.forEach(order -> orderService.cancelOrder(order.getId()));
}
}
- 實現訂單服務:在訂單服務中,我們實現查詢超時訂單和取消訂單的邏輯。
@Service
public class OrderService {
@Autowired
private OrderRepository orderRepository;
public List<Order> findTimeoutOrders() {
// 根據業務規則查詢超時訂單,例如:當前時間減去訂單建立時間大於超時閾值
return orderRepository.findByStatusAndCreateTimeBefore(OrderStatus.PENDING_PAYMENT, new Date(System.currentTimeMillis() - TIMEOUT_THRESHOLD));
}
public void cancelOrder(Long orderId) {
Order order = orderRepository.findById(orderId).orElse(null);
if (order != null && order.getStatus().equals(OrderStatus.PENDING_PAYMENT)) {
order.setStatus(OrderStatus.CANCELED);
orderRepository.save(order);
}
}
}
四、注意事項
-
定時任務的頻率:定時任務的頻率應根據業務需求和系統效能進行權衡。如果頻率過高,可能會增加系統負擔;如果頻率過低,可能導致訂單超時後不能及時取消。
-
異常處理:在定時任務或非同步處理中,應做好異常處理,避免因為某個訂單取消失敗而影響其他訂單的處理。
-
資料庫事務:在更新訂單狀態時,應注意資料庫事務的處理,確保資料的一致性。
透過以上步驟,我們可以在 Spring Boot 中實現訂單超時自動取消的策略。在實際應用中,還需要根據具體業務需求進行調整和最佳化。