这个SpringBoot飞机订票系统是一个典型的B/S架构企业级应用,我去年为某中型旅行社开发过类似系统。这类系统本质上要解决三个核心问题:航班资源的可视化呈现、实时库存管理和多角色协同操作。相比传统售票方式,系统能将机票销售效率提升3-5倍,同时降低超售风险。
技术栈选择SpringBoot不是偶然——我测试过用纯Servlet开发同类系统,仅处理高并发预订就需要多写40%的代码。SpringBoot的自动配置和starter依赖让开发者能聚焦业务逻辑,比如用Spring Data JPA处理航班余量更新,两行注解就实现了乐观锁控制。
采用经典的四层架构,但在数据访问层做了特殊设计:
code复制表现层(Thymeleaf)
业务逻辑层(Spring Service)
数据访问层(Spring Data JPA + 自定义Repository)
基础设施层(MySQL + Redis)
特别说明数据库选型:MySQL 8.0的窗口函数能高效计算航班上座率,而Redis的原子操作适合处理秒杀式特价票。我在库存服务层用@CacheEvict实现了二级缓存联动,避免超卖。
重要提示:永远不要在事务内直接调用第三方支付接口!我吃过亏——网络超时会导致数据库连接池耗尽。正确的做法是用Spring的@Async异步调用,通过事件驱动更新状态。
sql复制CREATE TABLE `flight` (
`id` bigint NOT NULL AUTO_INCREMENT,
`flight_no` varchar(10) COLLATE utf8mb4_bin NOT NULL COMMENT '航班号',
`departure_time` datetime NOT NULL,
`arrival_time` datetime NOT NULL,
`remaining_seats` int DEFAULT '0' COMMENT '动态计算的余票',
`version` int DEFAULT '0' COMMENT '乐观锁版本号',
PRIMARY KEY (`id`),
KEY `idx_departure` (`departure_time`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin;
余票计算采用触发器实现:
sql复制CREATE TRIGGER update_seats AFTER INSERT ON ticket_order
FOR EACH ROW
UPDATE flight SET remaining_seats = remaining_seats - NEW.seat_count
WHERE id = NEW.flight_id;
航班列表页的N+1问题是个坑:我最初用JPA的默认查询,200条数据产生201次SQL。解决方案:
java复制@EntityGraph(attributePaths = {"aircraft"})
@Query("SELECT f FROM Flight f WHERE f.departureTime > :now")
Page<Flight> findAvailableFlights(@Param("now") LocalDateTime now, Pageable pageable);
测试时发现200人同时抢10张票会出现超卖,最终方案:
java复制@Transactional
public BookingResult bookTicket(Long flightId, Integer seats) {
Flight flight = flightRepository.findByIdWithLock(flightId); // SELECT ... FOR UPDATE
if (flight.getRemainingSeats() < seats) {
throw new NoSeatAvailableException();
}
flight.setRemainingSeats(flight.getRemainingSeats() - seats);
flightRepository.save(flight);
// 生成订单...
}
配合前端采用倒计时15分钟保留座位,超时后通过Spring Scheduler自动释放库存。
使用Spring StateMachine实现状态管理:
java复制@Transition(source = "UNPAID", target = "PAID")
public void payOrder(Long orderId) {
Order order = orderRepository.findById(orderId);
if (order.getStatus() != OrderStatus.UNPAID) {
throw new IllegalStateException();
}
// 支付逻辑...
}
采用Docker Compose编排:
yaml复制services:
app:
image: openjdk:11-jre
ports:
- "8080:8080"
depends_on:
- redis
- mysql
mysql:
image: mysql:8.0
environment:
MYSQL_ROOT_PASSWORD: ${DB_PASSWORD}
redis:
image: redis:6-alpine
在application-prod.yml中关键配置:
yaml复制spring:
datasource:
hikari:
maximum-pool-size: 20
connection-timeout: 30000
jpa:
properties:
hibernate:
order_updates: true
order_inserts: true
batch_versioned_data: true
现象:前台显示有余票,下单时提示已售罄
原因:缓存未及时更新
解决:在@PostUpdate回调中手动清除Redis缓存
现象:支付宝回调成功但订单状态未更新
原因:网络问题导致回调丢失
解决:增加定时任务扫描超过30分钟的未支付订单,主动查询支付状态
系统特色部分建议突出:
性能对比数据示例:
论文结构参考:
markdown复制1. 引言(行业背景+痛点)
2. 关键技术分析(SpringBoot特性选型)
3. 系统设计(架构图+类图)
4. 核心实现(算法+并发控制)
5. 测试验证(JMeter压测结果)
6. 总结与展望
航班列表页优化:
订单确认页要点:
这个项目最让我有成就感的是解决了高并发场景下的数据一致性问题。建议开发时先用JMeter模拟200并发测试核心流程,你会惊讶地发现哪些简单的@Transactional注解根本扛不住真实流量。记住:永远在生产环境前做好全链路压测!