page contents

实现一个课程报名的业务逻辑,报名有名额,这个该如何设计

Pack 发布于 2020-02-06 18:01
阅读 422
收藏 0

问题描述

实现一个课程报名的业务逻辑,报名有名额(需要查询名额有剩余则进行注册,名额满了返回不可注册标示),这个该如何设计

问题出现的环境背景及自己尝试过哪些方法

之前考虑过线程池的单线程池,但是业务逻辑没有那么轻松,感觉不符合实际业务场景,请求大佬或者老师给个相关的建议或者示例。三克油!

260
Pack
Pack

这个业务是很常见的业务啊,主要就是并发控制,在并发情况下报名人数不能超过名额限制。这个和常问的卖商品时有库存限制,怎样控制不超卖是一个道理。

并发控制有几种办法,乐观锁,悲观锁,分布式锁(redis,zk都可实现)

感觉这课程报名的程序并发应该不高,所以用乐观锁就可以,实现简单。

具体实现:
比如课程表结构
id 课程名 名额 版本号

版本号字段为乐观锁控制使用的,可以设置初始化值为0;
报名的时候分这几步
1、首先获取到该课程的乐观锁
select * from 课程表 where 课程名=要报名的课程
update 课程表 set 版本号=版本号+1 where id=上一步查询到的id and 版本号=上一步查询到的版本号
检查update语句是否更新到了数据(返回值>0),更新到了数据就说明获取到了乐观锁,否则没获取到。

2、获取到了乐观锁
获取到锁后,判断课程名额是否还有。有就能报名,没有就提示报名人数已满
有名额的情况下,就可以执行报名的业务了,比如保存报名信息,减课程表对应课程的名额
减名额sql:update 课程表 set 名额=名额-1 where id=上面查询到的id

名额减了再执行其他业务逻辑。然后就结束了。

3、未获取到乐观锁
未获取到乐观锁的情况下,好的做法是等待一段时间(比如100ms)后进行重试,一般重试三次,三次都未获取到乐观锁,说明并发比较高,提示用户服务器忙,稍后重试。
但是重试的话,有一个点需要注意,要设置事物隔离级别为read_committed
@Transactional(isolation = Isolation.READ_COMMITTED,rollbackFor = Exception.class)

请先 登录 后评论