news 2026/7/14 8:44:28

基于Java与MySQL的航空订票系统核心模块设计与源码解析

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
基于Java与MySQL的航空订票系统核心模块设计与源码解析

1. 航空订票系统架构设计

航空订票系统本质上是一个典型的高并发事务处理系统,我在实际项目中采用分层架构设计。最底层是MySQL数据库层,中间是Java业务逻辑层,最上层是Web展示层。这种分层设计最大的好处是各层职责明确,修改任何一层都不会影响其他层。

数据库层我选择了MySQL 8.0,主要看中它的ACID特性和事务处理能力。在表结构设计上,我特别注意避免数据冗余。比如航班表和机票表是分开的,通过外键关联。这样当航班信息变更时,只需要修改一处即可。

业务逻辑层采用Spring Boot框架,它内置的Tomcat容器能轻松应对数百并发请求。我特别使用了Spring的事务管理,确保订票过程中的多个数据库操作要么全部成功,要么全部回滚。比如用户支付成功后,系统需要同时减少座位数和生成订单,这两个操作必须在一个事务中完成。

Web层采用Thymeleaf模板引擎,相比JSP更轻量级。前端页面做了静态资源缓存,减少服务器压力。对于高并发的航班查询请求,我加入了Redis缓存,将热门航线信息缓存起来,实测查询性能提升了5倍以上。

2. 核心数据库表设计

2.1 航班信息表设计

航班表(flight)是整个系统的核心,字段设计直接影响查询效率。我采用以下关键字段:

CREATE TABLE `flight` ( `id` bigint NOT NULL AUTO_INCREMENT, `flight_no` varchar(20) NOT NULL COMMENT '航班号', `departure_city` varchar(50) NOT NULL, `arrival_city` varchar(50) NOT NULL, `departure_time` datetime NOT NULL, `arrival_time` datetime NOT NULL, `aircraft_type` varchar(30) DEFAULT NULL, `total_seats` int DEFAULT '0' COMMENT '总座位数', `available_seats` int DEFAULT '0' COMMENT '可用座位数', `price` decimal(10,2) DEFAULT NULL, PRIMARY KEY (`id`), KEY `idx_city_time` (`departure_city`,`arrival_city`,`departure_time`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

特别注意创建了联合索引idx_city_time,这对提高按城市和时间的查询速度非常关键。实测在有索引的情况下,百万级数据量的查询能在50ms内完成。

2.2 订单表设计

订单表(order)需要记录完整的交易信息,我采用状态字段来跟踪订单生命周期:

CREATE TABLE `order` ( `id` bigint NOT NULL AUTO_INCREMENT, `order_no` varchar(32) NOT NULL COMMENT '订单编号', `user_id` bigint NOT NULL, `flight_id` bigint NOT NULL, `passenger_name` varchar(100) NOT NULL, `id_card_no` varchar(18) NOT NULL, `seat_type` tinyint DEFAULT '1' COMMENT '1经济舱 2商务舱', `amount` decimal(10,2) NOT NULL, `status` tinyint DEFAULT '0' COMMENT '0待支付 1已支付 2已取消', `create_time` datetime NOT NULL, `update_time` datetime NOT NULL, PRIMARY KEY (`id`), UNIQUE KEY `uk_order_no` (`order_no`), KEY `idx_user` (`user_id`), KEY `idx_flight` (`flight_id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

订单号使用UUID生成确保唯一性。status字段的设计让系统可以轻松扩展新的订单状态,比如退款中、已完成等。

3. 关键业务逻辑实现

3.1 航班查询功能

航班查询是最频繁的操作,我采用缓存+数据库的查询策略:

public List<Flight> searchFlights(String departure, String arrival, Date date) { String cacheKey = "flight:" + departure + ":" + arrival + ":" + new SimpleDateFormat("yyyyMMdd").format(date); // 先查Redis缓存 String cached = redisTemplate.opsForValue().get(cacheKey); if (cached != null) { return JSON.parseArray(cached, Flight.class); } // 缓存没有则查数据库 List<Flight> flights = flightMapper.selectByCitiesAndDate(departure, arrival, date); // 设置缓存,过期时间30分钟 if (!flights.isEmpty()) { redisTemplate.opsForValue().set(cacheKey, JSON.toJSONString(flights), 30, TimeUnit.MINUTES); } return flights; }

对于热门航线,这种设计能减少90%以上的数据库查询。缓存过期时间设置为30分钟,既保证了数据新鲜度,又避免了频繁查询数据库。

3.2 订票事务处理

订票是典型的分布式事务场景,我采用本地事务+消息队列的方案:

@Transactional public Order createOrder(Long flightId, Long userId, PassengerInfo passenger) { // 1. 查询航班信息 Flight flight = flightMapper.selectById(flightId); if (flight == null) { throw new BizException("航班不存在"); } // 2. 检查余票 if (flight.getAvailableSeats() <= 0) { throw new BizException("航班已售罄"); } // 3. 扣减库存 int updated = flightMapper.reduceSeat(flightId); if (updated == 0) { throw new BizException("座位已被其他用户锁定"); } // 4. 生成订单 Order order = new Order(); order.setOrderNo(generateOrderNo()); order.setFlightId(flightId); order.setUserId(userId); order.setPassengerName(passenger.getName()); order.setIdCardNo(passenger.getIdCard()); order.setAmount(flight.getPrice()); order.setStatus(OrderStatus.UNPAID.getCode()); order.setCreateTime(new Date()); order.setUpdateTime(new Date()); orderMapper.insert(order); // 5. 发送支付超时消息 sendPaymentTimeoutMessage(order.getOrderNo()); return order; }

这个实现有几个关键点:

  1. 使用@Transactional确保减库存和生成订单的原子性
  2. 使用乐观锁防止超卖
  3. 订单生成后发送延迟消息,30分钟后检查支付状态

4. 并发控制与性能优化

4.1 解决超卖问题

航空订票最怕的就是超卖,我采用三种措施防止超卖:

  1. 数据库乐观锁:
@Update("UPDATE flight SET available_seats = available_seats - 1 WHERE id = #{id} AND available_seats > 0") int reduceSeat(Long id);
  1. Redis分布式锁:
public boolean lockSeat(Long flightId) { String lockKey = "seat_lock:" + flightId; return redisTemplate.opsForValue().setIfAbsent(lockKey, "1", 10, TimeUnit.SECONDS); }
  1. 异步库存校验: 订单创建后,会有定时任务检查实际库存与订单是否匹配,发现不一致会自动取消订单并通知用户。

4.2 性能优化实践

在高并发场景下,我做了以下优化:

  1. 使用连接池:配置HikariCP连接池,最大连接数设置为100
spring.datasource.hikari.maximum-pool-size=100 spring.datasource.hikari.connection-timeout=30000
  1. 慢查询优化:通过EXPLAIN分析慢查询,添加适当索引

  2. 读写分离:查询走从库,写入走主库

  3. 分库分表:当订单表超过500万时,按用户ID哈希分表

5. 安全设计与异常处理

5.1 支付安全设计

支付环节我采用以下安全措施:

  1. 所有敏感信息如身份证号在数据库加密存储
public String encryptIdCard(String idCard) { return EncryptUtil.aesEncrypt(idCard, secretKey); }
  1. 支付请求签名验证
public boolean verifySign(PaymentRequest request) { String raw = request.getOrderNo() + request.getAmount() + salt; return DigestUtils.md5Hex(raw).equals(request.getSign()); }
  1. 支付结果异步通知校验

5.2 异常处理策略

系统定义了一套完整的异常处理机制:

@ControllerAdvice public class GlobalExceptionHandler { @ExceptionHandler(BizException.class) @ResponseBody public Result handleBizException(BizException e) { return Result.fail(e.getCode(), e.getMessage()); } @ExceptionHandler(Exception.class) @ResponseBody public Result handleException(Exception e) { log.error("系统异常", e); return Result.fail(500, "系统繁忙,请稍后再试"); } }

对于预期内的业务异常如"座位已售罄",返回明确的错误提示;对于系统异常,记录详细日志并返回友好提示。

6. 系统扩展与演进

随着业务增长,系统架构也在不断演进:

  1. 服务拆分:将原本的单体应用拆分为航班服务、订单服务、支付服务等

  2. 引入消息队列:使用RocketMQ处理异步任务如发送行程单

  3. 分布式事务:采用Seata处理跨服务的分布式事务

  4. 弹性设计:增加熔断降级机制,当航班查询服务不可用时返回缓存数据

这些架构演进保证了系统能够支撑从日订单几百到上万的平滑过渡。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/7/14 8:44:24

Windows系统appsruprov.dll丢失修复指南

1. appsruprov.dll文件丢失问题解析 appsruprov.dll是Windows系统中一个重要的动态链接库文件&#xff0c;全称为Application System Resource Usage Monitor (SRUM) provider。这个文件主要用于监控和记录应用程序对系统资源的使用情况&#xff0c;是Windows系统资源监控机制的…

作者头像 李华
网站建设 2026/7/14 8:43:46

从技术博客到实战应用:LongCat-2.0生态系统的完整路线图

从技术博客到实战应用&#xff1a;LongCat-2.0生态系统的完整路线图 【免费下载链接】LongCat-2.0 项目地址: https://ai.gitcode.com/meituan-longcat/LongCat-2.0 想要了解如何从技术博客阅读走向实际应用部署LongCat-2.0大语言模型吗&#xff1f;本文将为你提供完整…

作者头像 李华
网站建设 2026/7/14 8:42:33

APAddressBook性能优化:提升iOS通讯录数据加载速度的5个技巧

APAddressBook性能优化&#xff1a;提升iOS通讯录数据加载速度的5个技巧 【免费下载链接】APAddressBook Easy access to iOS address book 项目地址: https://gitcode.com/gh_mirrors/ap/APAddressBook APAddressBook是一款专注于简化iOS通讯录访问的开发框架&#xff…

作者头像 李华
网站建设 2026/7/14 8:41:36

Linux 服务器运维:如何彻底禁用休眠与挂起以保障服务稳定

1. 为什么服务器需要禁用休眠与挂起&#xff1f; 我第一次管理生产服务器时就踩过这个坑。那是个普通的周二凌晨3点&#xff0c;监控系统突然报警——所有服务全部离线。我手忙脚乱赶到机房&#xff0c;发现服务器指示灯正常&#xff0c;但所有网络服务无响应。后来才发现是系统…

作者头像 李华