学员的学习记录增加爱锁控制

This commit is contained in:
none 2023-04-25 10:23:57 +08:00
parent abf6a36c4f
commit 246cfe6501
5 changed files with 34 additions and 12 deletions

View File

@ -60,6 +60,7 @@ public class UserBus {
return CollectionUtils.intersection(courseDepIds, userDepIds).size() > 0;
}
// 注意调用该方法需要考虑到并发写入问题
public void userLearnDurationRecord(User user, Course course, CourseHour hour) {
Long curTime = System.currentTimeMillis();

View File

@ -32,8 +32,10 @@ import xyz.playedu.api.service.CourseService;
import xyz.playedu.api.service.ResourceService;
import xyz.playedu.api.service.UserCourseHourRecordService;
import xyz.playedu.api.types.JsonResponse;
import xyz.playedu.api.util.RedisDistributedLock;
import java.util.HashMap;
import java.util.concurrent.TimeUnit;
/**
* @Author 杭州白书科技有限公司
@ -58,6 +60,8 @@ public class HourController {
@Autowired private UserCanSeeCourseCache userCanSeeCourseCache;
@Autowired private CourseCache courseCache;
@Autowired private RedisDistributedLock redisDistributedLock;
@GetMapping("/{id}")
@SneakyThrows
public JsonResponse detail(
@ -108,13 +112,23 @@ public class HourController {
if (duration <= 0) {
return JsonResponse.error("duration参数错误");
}
User user = FCtx.getUser();
Course course = courseCache.findOrFail(courseId);
userCanSeeCourseCache.check(user, course, true);
CourseHour hour = hourService.findOrFail(id, courseId);
userCanSeeCourseCache.check(FCtx.getUser(), course, true);
// 获取锁
String lockKey = String.format("record:%d", FCtx.getId());
boolean tryLock = redisDistributedLock.tryLock(lockKey, 5, TimeUnit.SECONDS);
if (!tryLock) {
return JsonResponse.error("请稍后再试");
}
userCourseHourRecordService.storeOrUpdate(
user.getId(), course.getId(), hour.getId(), duration, hour.getDuration());
FCtx.getId(), course.getId(), hour.getId(), duration, hour.getDuration());
// 此处未考虑上面代码执行失败释放锁
redisDistributedLock.releaseLock(lockKey);
return JsonResponse.success();
}
@ -127,7 +141,19 @@ public class HourController {
Course course = courseCache.findOrFail(courseId);
CourseHour hour = hourService.findOrFail(id, courseId);
userCanSeeCourseCache.check(FCtx.getUser(), course, true);
// 获取锁
String lockKey = String.format("ping:%d", FCtx.getId());
boolean tryLock = redisDistributedLock.tryLock(lockKey, 5, TimeUnit.SECONDS);
if (!tryLock) {
return JsonResponse.error("请稍后再试");
}
userBus.userLearnDurationRecord(FCtx.getUser(), course, hour);
// 此处未考虑上面代码执行失败释放锁
redisDistributedLock.releaseLock(lockKey);
return JsonResponse.success();
}
}

View File

@ -17,7 +17,6 @@ package xyz.playedu.api.listener;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.event.EventListener;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Component;
import xyz.playedu.api.event.UserCourseHourFinishedEvent;
@ -39,7 +38,6 @@ public class UserCourseHourFinishedListener {
@Autowired private CourseHourService hourService;
@Async
@EventListener
public void userCourseProgressUpdate(UserCourseHourFinishedEvent evt) {
Integer hourCount = hourService.getCountByCourseId(evt.getCourseId());

View File

@ -19,7 +19,6 @@ import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.event.EventListener;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Component;
import xyz.playedu.api.event.UserLearnCourseUpdateEvent;
@ -39,7 +38,6 @@ public class UserLearnCourseUpdateListener {
@Autowired private UserLearnDurationStatsService userLearnDurationStatsService;
@Async
@EventListener
public void storeLearnDuration(UserLearnCourseUpdateEvent event) {
// 观看时长统计

View File

@ -15,6 +15,8 @@
*/
package xyz.playedu.api.service.impl;
import cn.hutool.core.date.DateTime;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.SneakyThrows;
@ -42,10 +44,7 @@ public class UserLearnDurationStatsServiceImpl
@Override
@SneakyThrows
public void storeOrUpdate(Integer userId, Long startTime, Long endTime) {
// 处理日期
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
String date = simpleDateFormat.format(new Date(endTime));
// duration
String date = new DateTime().toDateStr();
Long duration = endTime - startTime;
UserLearnDurationStats stats =
@ -54,7 +53,7 @@ public class UserLearnDurationStatsServiceImpl
UserLearnDurationStats newStats = new UserLearnDurationStats();
newStats.setUserId(userId);
newStats.setDuration(duration);
newStats.setCreatedDate(simpleDateFormat.parse(date));
newStats.setCreatedDate(new DateTime(date));
save(newStats);
return;
}