You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

实现用户预订座位时可用座位数自动减1的Java+MySQL方案咨询

实现预订座位自动扣减的解决方案

你不需要用数组实现该功能,数组属于内存临时存储,服务重启后数据会重置,多用户并发访问时也会出现数据不一致的问题,直接通过数据库事务操作就能可靠实现需求。

核心实现逻辑

  • 先查询对应车次的当前可用座位数,校验是否大于0
  • 开启数据库事务,同时执行两个操作:插入预订记录、将对应车次可用座位数减1
  • 两个操作都成功则提交事务,任意一个失败就回滚,避免数据不一致
  • 操作完成后刷新页面/组件上的可用座位展示值

修改后的代码示例

try {
    String route_number = rnB.getText();
    String depature_on = doB.getText();
    String depature_time = dtB.getText();

    Connection connection = DriverManager.getConnection("jdbc:mysql://localhost:3306/eurobusdb?useSSL=false","root","Abc123");
    // 关闭自动提交,开启事务
    connection.setAutoCommit(false);

    // 第一步:先查询当前车次的可用座位数,校验可预订性
    String QUERY_SEATS_SQL = "SELECT available_seats FROM bus_schedule WHERE route = ? AND depature_on = ? AND depature_time = ? FOR UPDATE";
    PreparedStatement queryPs = connection.prepareStatement(QUERY_SEATS_SQL);
    queryPs.setString(1, route_number);
    queryPs.setString(2, depature_on);
    queryPs.setString(3, depature_time);
    ResultSet rs = queryPs.executeQuery();
    int availableSeats = 0;
    if(rs.next()){
        availableSeats = rs.getInt("available_seats");
    }
    if(availableSeats <= 0){
        throw new Exception("当前车次已无可用座位,预订失败");
    }

    // 第二步:插入预订记录
    String SQL_INSERT_BOOKING = "INSERT INTO booking (Depature_Country_And_City , Destination_Country_And_City, Depature_On, Depature_Time, Estimated_Time_Taken, Available_Seats, Price, Status, route, name, contact_number) VALUES ( ?,?,?,?,?,?,?,?,?,?,?);";
    PreparedStatement insertPs = connection.prepareStatement(SQL_INSERT_BOOKING);
    insertPs.setString(1, String.valueOf(combo1.getSelectedItem()));
    insertPs.setString(2, String.valueOf(combo2.getSelectedItem()));
    insertPs.setString(3, depature_on);
    insertPs.setString(4, depature_time);
    insertPs.setString(5, timeB.getText());
    // 这里存预订时的剩余座位数,扣减前的数或者扣减后的可根据业务需求调整
    insertPs.setString(6, String.valueOf(availableSeats - 1));
    insertPs.setString(7, pB.getText());
    insertPs.setString(8, "Booked");
    insertPs.setString(9, route_number);
    insertPs.setString(10, name.getText());
    insertPs.setString(11, contact.getText());
    insertPs.executeUpdate();

    // 第三步:更新车次可用座位数,扣减1
    String UPDATE_SEATS_SQL = "UPDATE bus_schedule SET available_seats = available_seats - 1 WHERE route = ? AND depature_on = ? AND depature_time = ?";
    PreparedStatement updatePs = connection.prepareStatement(UPDATE_SEATS_SQL);
    updatePs.setString(1, route_number);
    updatePs.setString(2, depature_on);
    updatePs.setString(3, depature_time);
    updatePs.executeUpdate();

    // 提交事务
    connection.commit();

    // 刷新页面上的可用座位展示
    asb.setText(String.valueOf(availableSeats - 1));

} catch (Exception e) {
    // 出现异常回滚事务
    if(connection != null){
        try {
            connection.rollback();
        } catch (SQLException ex) {
            ex.printStackTrace();
        }
    }
    e.printStackTrace();
    // 这里可以加弹窗提示用户预订失败的原因
} finally {
    // 关闭连接等资源
    if(connection != null){
        try {
            connection.close();
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }
}

注意事项

  • 你需要提前在数据库中创建车次调度表bus_schedule,字段至少包含route(车次号)、depature_on(发车日期)、depature_time(发车时间)、available_seats(可用座位数),初始化时对应车次的available_seats设为35即可
  • 查询可用座位时加FOR UPDATE是为了加行锁,避免并发预订时出现超卖问题
  • 原代码中你直接调用组件的toString()方法是错误的,应该调用getText()方法获取输入的内容

内容的提问来源于stack exchange,提问作者Vimesh Perera

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.28 10:06:03