抽奖系统作为企事业单位年会、庆典、促销活动的标配环节,其公平性和随机性直接影响活动公信力。传统人工抽奖方式存在效率低、透明度不足等问题,而简单的随机数生成又难以满足复杂业务场景需求。这个2026届毕业设计项目采用SSM框架(Spring+SpringMVC+MyBatis)结合Java技术栈,构建了一个支持多维度随机算法、可视化结果展示的抽奖管理系统。
核心解决三个痛点:
采用Spring 5.3.x + SpringMVC + MyBatis 3.5.x组合,相比传统Servlet/JSP方案:
java复制// 典型Controller示例
@Controller
@RequestMapping("/draw")
public class DrawController {
@Autowired
private DrawService drawService;
@PostMapping("/start")
@ResponseBody
public Result startDraw(@RequestParam Integer activityId) {
return drawService.startDraw(activityId);
}
}
系统集成三种随机算法:
关键点:SecureRandom虽然性能比Random低30%,但避免了线性同余算法的可预测性
采用状态机模式管理抽奖生命周期:
code复制待开始 → 进行中 → 已结束
↘ 暂停中
数据库设计关键表:
sql复制CREATE TABLE t_activity (
id INT PRIMARY KEY AUTO_INCREMENT,
name VARCHAR(100) NOT NULL,
total_prize INT DEFAULT 0,
status TINYINT COMMENT '0-待开始 1-进行中 2-暂停 3-已结束'
);
CREATE TABLE t_draw_record (
id BIGINT PRIMARY KEY,
activity_id INT,
user_id INT,
prize_id INT,
draw_time DATETIME
);
通过三级缓存应对瞬时高峰:
实测数据:
使用NIST STS测试套件验证随机性:
| 算法类型 | 测试用例数 | 通过率 | 平均耗时(ms) |
|---|---|---|---|
| Java Random | 10000 | 72.3% | 1.2 |
| SecureRandom | 10000 | 98.6% | 4.8 |
| 权重算法 | 10000 | 95.2% | 8.3 |
问题现象:高并发时出现奖品超发
原因定位:
解决方案:
java复制// Redis原子操作示例
String script = "if tonumber(redis.call('get', KEYS[1])) > 0 then " +
"return redis.call('decr', KEYS[1]) " +
"else return -1 end";
redisTemplate.execute(new DefaultRedisScript<>(script, Long.class),
Collections.singletonList("stock:"+prizeId));
xml复制<insert id="batchInsert" useGeneratedKeys="true" keyProperty="id">
INSERT INTO t_draw_record VALUES
<foreach collection="list" item="item" separator=",">
(#{item.activityId},#{item.userId},#{item.prizeId},NOW())
</foreach>
</insert>
properties复制# application.properties
spring.transaction.default-timeout=30
技术论文应包含以下核心章节:
图表规范建议:
实际开发中发现,当参与人数超过1万时,MySQL的GROUP BY查询会成为性能瓶颈。后来通过添加复合索引(activity_id, prize_id)并将统计结果预计算到Redis,查询耗时从1200ms降至80ms。这个优化过程值得在论文的"性能调优"章节详细说明。