【備戰春招】第21天 redis 避免超售
標簽:
SpringBoot
课程名称:SpringBoot2.X + Vue + UniAPP,全栈开发医疗小程序
课程章节: 第1章
课程讲师:神思者
课程内容
声明SQL语句 查询openid
<select id="searchOpenId" parameterType="int" resultType="HashMap">
SELECT u."open_id" AS "openId",
c."id" AS "patientCardId"
FROM HOSPITAL.PATIENT_USER u
JOIN HOSPITAL.PATIENT_USER_INFO_CARD c ON c."user_id"=u."id"
WHERE u."id" = #{userId}</select>声明 dao
public interface UserDao {
public HashMap searchOpenId(int userId);
}MedicalRegistrationDao 编写 更新
<insert id="insert" parameterType="com.example.hospital.patient.wx.api.db.pojo.MedicalRegistrationEntity">
UPSERT INTO HOSPITAL.MEDICAL_REGISTRATION(
"id", "patient_card_id", "work_plan_id", "doctor_schedule_id",
"doctor_id", "dept_sub_id", "date", "slot", "amount",
"out_trade_no", "prepay_id", "payment_status", "create_time"
)
VALUES(
NEXT VALUE FOR HOSPITAL.MEDICAL_REGISTRATION_SEQUENCE, ${patientCardId}, ${workPlanId}, ${doctorScheduleId},
${doctorId}, ${deptSubId}, TO_DATE('${date}'), ${slot}, ${amount},
#{outTradeNo}, #{prepayId}, 1, NOW()
)</insert>DoctorWorkPlanDao 将查到的数据加上n
<update id="updateNumById" parameterType="Map">
UPSERT INTO HOSPITAL.DOCTOR_WORK_PLAN("id","num")
SELECT "id",
"num" + ${n} AS "num"
FROM HOSPITAL.DOCTOR_WORK_PLAN
WHERE "id" = ${id}</update>编写业务层
@Servicepublic class RegistrationServiceImpl implements RegistrationService {
@Resource
private UserDao userDao;
@Resource
private RedisTemplate redisTemplate;
…… @Override
@Transactional
public HashMap registerMedicalAppointment(Map param) {
int workPlanId = MapUtil.getInt(param, "workPlanId");
int scheduleId = MapUtil.getInt(param, "scheduleId");
//检查Redis中是否存在日程缓存(过期的出诊计划和时段会自动删除),不存在缓存就不执行挂号
String key = "doctor_schedule_" + scheduleId;
if (!redisTemplate.hasKey(key)) {
return null;
}
//Redis事务代码必须写到execute()回调函数中
Object execute = redisTemplate.execute(new SessionCallback() {
@Override
public Object execute(RedisOperations operations) throws DataAccessException {
//关注缓存数据(拿到乐观锁的Version)
operations.watch(key);
//拿到缓存的数据
Map entry = operations.opsForHash().entries(key);
//拿到缓存该时段最大接诊人数和已挂号人数
int maximum = Integer.parseInt(entry.get("maximum").toString());
int num = Integer.parseInt(entry.get("num").toString());
//如果已挂号人数小于最大人数就可以挂号
if (num < maximum) {
//开启Redis事务
operations.multi();
//已挂号人数+1
operations.opsForHash().increment(key, "num", 1);
//提交事务
return operations.exec();
}
//到达挂号人数上限就不执行挂号
else {
operations.unwatch();
return null;
}
}
});
//如果Redis事务提交失败就结束Service方法
if (execute == null) {
return null;
}
//如果Redis事务提交成功,就执行下面的代码
try {
//TODO 创建支付订单
//TODO 保存挂号记录
//TODO 更新数据库中的该时段挂号人数和该医生当日挂号实际人数
//TODO 在Redis中缓存付款记录,并设置过期时间
} catch (Exception e) {
if (redisTemplate.hasKey(key)) {
//恢复缓存该日程已经挂号数量
redisTemplate.opsForHash().increment(key, "num", -1);
}
throw e;
}
}}點擊查看更多內容
為 TA 點贊
評論
評論
共同學習,寫下你的評論
評論加載中...
作者其他優質文章
正在加載中
感謝您的支持,我會繼續努力的~
掃碼打賞,你說多少就多少
贊賞金額會直接到老師賬戶
支付方式
打開微信掃一掃,即可進行掃碼打賞哦

