设计一个购票系统
设计购票系统时,需要考虑到不同的功能模块,如用户、订单、支付和票管理等。以下是相关数据表的设计及关键Java伪代码实现,并发处理和数据一致性方面的考虑。
数据库表设计
-
用户表 (
users
)-
user_id
(主键) username
balance
-
-
票表 (
tickets
)-
ticket_id
(主键) -
status
(例如 available, sold)
-
-
订单表 (
orders
)-
order_id
(主键) -
user_id
(外键, 参照users.user_id
) -
ticket_id
(外键, 参照tickets.ticket_id
, 可为空) amount
-
status
(如 pending, success, failed, withdrawn)
-
-
队列表 (
queue
)-
queue_id
(主键) -
user_id
(外键, 参照users.user_id
) -
status
(如 in_queue, withdrawn)
-
核心伪代码实现
class TicketingSystem {
private final PaymentService paymentService;
private final TicketService ticketService;
private final OrderService orderService;
private final QueueService queueService;
public TicketingSystem() {
// Initialize services
paymentService = new PaymentService();
ticketService = new TicketService();
orderService = new OrderService();
queueService = new QueueService();
}
// 用户提交购票申请
public void submitTicketRequest(int userId, double prePaymentAmount) {
synchronize (this) {
if (queueService.isUserInQueue(userId)) {
throw new IllegalStateException("User already in queue");
}
// 创建订单
int orderId = orderService.createOrder(userId, prePaymentAmount, OrderStatus.PENDING);
// 将用户加入队列
queueService.addUserToQueue(userId);
}
}
// 查询排队人数
public int getQueuePosition(int userId) {
return queueService.getQueuePosition(userId);
}
// 后台处理购票请求
public void processTicketRequests() {
while (true) {
int userId = queueService.getNextUserInQueue();
if (userId == -1) break;
Order order = orderService.getPendingOrderByUserId(userId);
if (order == null) continue;
synchronize (this) {
if (paymentService.freezeAmount(userId, order.getAmount())) {
int ticketId = ticketService.allocateTicket(order.getOrderId());
if (ticketId != -1) {
// 扣款并更新订单状态
paymentService.debitAmount(userId, order.getAmount());
orderService.updateOrderStatus(order.getOrderId(), OrderStatus.SUCCESS);
orderService.updateOrderTicket(order.getOrderId(), ticketId);
queueService.removeUserFromQueue(userId);
} else {
// 出票失败,解冻用户金额并更新订单状态
paymentService.unfreezeAmount(userId, order.getAmount());
orderService.updateOrderStatus(order.getOrderId(), OrderStatus.FAILED);
}
} else {
orderService.updateOrderStatus(order.getOrderId(), OrderStatus.FAILED);
}
}
}
}
// 用户撤回购票申请
public void withdrawTicketRequest(int userId) {
synchronize (this) {
if (!queueService.isUserInQueue(userId)) {
throw new IllegalStateException("User is not in the queue");
}
queueService.removeUserFromQueue(userId);
Order order = orderService.getPendingOrderByUserId(userId);
if (order != null && order.getStatus() == OrderStatus.PENDING) {
orderService.updateOrderStatus(order.getOrderId(), OrderStatus.WITHDRAWN);
paymentService.unfreezeAmount(userId, order.getAmount());
}
}
}
}
class PaymentService {
// 预付款冻结资金
public boolean freezeAmount(int userId, double amount) {
// 逻辑实现
}
// 扣款
public void debitAmount(int userId, double amount) {
// 逻辑实现
}
// 解冻金额
public void unfreezeAmount(int userId, double amount) {
// 逻辑实现
}
}
class TicketService {
// 分配票
public int allocateTicket(int orderId) {
// 逻辑实现(并发时注意减小锁粒度)
}
}
class OrderService {
// 创建订单
public int createOrder(int userId, double amount, OrderStatus status)