Browse Source

3.25 订座系统 修改bug

milestone-20260324-订座
huangqizhen 2 weeks ago
parent
commit
7baeab95ee
  1. 20
      lottery-system/lottery-service/src/main/java/com/lottery/api/service/SeatAsyncSaveService.java
  2. 10
      lottery-system/lottery-service/src/main/java/com/lottery/api/service/SeatSelectionService.java
  3. 18
      lottery-system/lottery-service/src/main/java/com/lottery/config/AsyncConfig.java
  4. 5
      lottery-system/lottery-service/src/main/java/com/lottery/interceptor/AuthInterceptor.java
  5. 17
      lottery-system/lottery-service/src/main/java/com/lottery/interceptor/SeatRepository.java

20
lottery-system/lottery-service/src/main/java/com/lottery/api/service/SeatAsyncSaveService.java

@ -1,7 +1,10 @@
package com.lottery.api.service;
import com.lottery.entity.Seat;
import com.lottery.entity.SeatStatus;
import com.lottery.interceptor.SeatRepository;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
@ -16,6 +19,23 @@ public class SeatAsyncSaveService {
@PersistenceContext
private EntityManager entityManager;
@Autowired
private SeatRepository seatRepository;
@Async("seatExecutor") // 复用你现有的线程池配置
@Transactional(propagation = Propagation.REQUIRES_NEW) // 确保独立事务提交
public void updateStatusByUniqueId(String lockedBy, SeatStatus status) {
int affected = seatRepository.updateStatusByUniqueId(lockedBy, status);
// 🔥 关键记录更新结果便于排查
if (affected == 0) {
log.warn("座位更新失败: uniqueId={}, 可能不存在或已被释放", lockedBy);
// 可选集成告警/监控
} else {
log.debug("座位释放成功: uniqueId={}, affected={}", lockedBy, affected);
}
}
@Async("taskExecutor") // 指定线程池
@Transactional(propagation = Propagation.REQUIRES_NEW)

10
lottery-system/lottery-service/src/main/java/com/lottery/api/service/SeatSelectionService.java

@ -345,14 +345,8 @@ public class SeatSelectionService {
// 4. 删除用户 - 座位映射
redisTemplate.delete(userSeatKey);
// 5. 异步更新数据库
Seat releasedSeat = Seat.builder()
.tableNo(tableNo)
.seatNo(seatNo)
.uniqueId(seatId)
.status(SeatStatus.AVAILABLE)
.build();
seatAsyncSaveService.save(releasedSeat); // 确保你的 asyncSaveService 支持更新
// 5. 异步更新数据库 🔥 直接调用 repository UPDATE 方法
seatAsyncSaveService.updateStatusByUniqueId(userId, SeatStatus.AVAILABLE);
// 6. 广播状态变更
SeatUpdateEvent event = SeatUpdateEvent.builder()

18
lottery-system/lottery-service/src/main/java/com/lottery/config/AsyncConfig.java

@ -31,4 +31,22 @@ public class AsyncConfig {
executor.initialize();
return executor;
}
@Bean("seatExecutor") // 关键Bean 名称必须匹配
public Executor seatExecutor() {
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
// 核心参数根据业务 QPS 调整
executor.setCorePoolSize(4); // 核心线程数
executor.setMaxPoolSize(10); // 最大线程数
executor.setQueueCapacity(100); // 队列容量
executor.setKeepAliveSeconds(60); // 空闲线程存活时间
executor.setThreadNamePrefix("seat-async-"); // 线程名前缀便于日志追踪
executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy()); // 拒绝策略
executor.setWaitForTasksToCompleteOnShutdown(true); // 优雅关闭
executor.setAwaitTerminationSeconds(30);
executor.initialize(); // 🔥 必须调用否则配置不生效
return executor;
}
}

5
lottery-system/lottery-service/src/main/java/com/lottery/interceptor/AuthInterceptor.java

@ -70,7 +70,10 @@ public class AuthInterceptor implements HandlerInterceptor {
if ("/api/health".equals(request.getRequestURI())) {
return true;
}
if ("/ws/seat".equals(request.getRequestURI())){
if ("/ws/seat/*".equals(request.getRequestURI())){
return true;
}
if ("/api/seat/cancel".equals(request.getRequestURI())){
return true;
}

17
lottery-system/lottery-service/src/main/java/com/lottery/interceptor/SeatRepository.java

@ -24,16 +24,19 @@ public interface SeatRepository extends JpaRepository<Seat, Long> {
Optional<Seat> findByUniqueId(String uniqueId);
/**
* 更新座位状态 👇 必须加 @Modifying + @Query
*/
@Modifying
@Query("UPDATE Seat s SET s.status = :status WHERE s.uniqueId = :uniqueId")
int updateStatusByUniqueId(@Param("uniqueId") String uniqueId, @Param("status") SeatStatus status);
/**
* 释放用户的所有锁定座位
*/
@Modifying
@Query("UPDATE Seat s SET s.status = 'AVAILABLE', s.lockedBy = NULL WHERE s.lockedBy = :lockedBy")
int releaseSeatsByUser(@Param("lockedBy") String lockedBy);
@Modifying(clearAutomatically = true, flushAutomatically = true)
@Query("UPDATE Seat s SET s.status = :status, " +
"s.lockedBy = null, " +
"s.lockedAt = null " +
"WHERE s.lockedBy = :lockedBy")
int updateStatusByUniqueId(@Param("lockedBy") String lockedBy,
@Param("status") SeatStatus status);
}
Loading…
Cancel
Save