Redis教程

【备战春招】第21天 redis 避免超售

本文主要是介绍【备战春招】第21天 redis 避免超售,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!

课程名称:SpringBoot2.X + Vue + UniAPP,全栈开发医疗小程序




课程章节: 第1章




课程讲师:神思者




课程内容



https://img4.sycdn.imooc.com/63fd46980001399c13180606.jpg



声明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;
        }
    }}



https://img4.sycdn.imooc.com/63fd47bf00015b5908650466.jpg

























这篇关于【备战春招】第21天 redis 避免超售的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!