A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

【郑州校区】学成在线-第19天-讲义-分布式事务 九

4 自动添加选课开发
4.1 学习服务添加选课
4.1.1需求分析
学习服务接收MQ发送添加选课消息,执行添加 选 课操作。
添加选课成功向学生选课表插入记录、向历史任务表插入记录、并向MQ发送完成选课消息。
4.1.2 RabbitMQ配置
学习服务监听MQ的添加选课队列,并且声明完成选课队列,配置代码同订单服务中RabbitMQ配置
4.1.3 Dao
学生选课Dao
[AppleScript] 纯文本查看 复制代码
 public interface XcLearningCourseRepository extends JpaRepository<XcLearningCourse, String> {
//根据用户和课程查询选课记录,用于判断是否添加选课
XcLearningCourse findXcLearningCourseByUserIdAndCourseId(String userId, String courseId);
}

历史任务Dao
[AppleScript] 纯文本查看 复制代码
 public interface XcTaskHisRepository extends JpaRepository<XcTaskHis,String> {
}


4.1.4 Service
1、添加选课方法
xc_learning_course添加记录,为保证不重复添加选课,先查询历史任务表,如果从历史任务表查询不到任务说
明此任务还没有处理,此时则添加选课并添加历史任务。
在学习服务中编码如下代码:
[AppleScript] 纯文本查看 复制代码
 //完成选课
@Transactional
public ResponseResult addcourse(String userId, String courseId,String valid,Date
startTime,Date endTime,XcTask xcTask){
if (StringUtils.isEmpty(courseId)) {
ExceptionCast.cast(LearningCode.LEARNING_GETMEDIA_ERROR);
}
if (StringUtils.isEmpty(userId)) {
ExceptionCast.cast(LearningCode.CHOOSECOURSE_USERISNULL);
}
if(xcTask == null || StringUtils.isEmpty(xcTask.getId())){
ExceptionCast.cast(LearningCode.CHOOSECOURSE_TASKISNULL);
}
//查询历史任务
Optional<XcTaskHis> optional = xcTaskHisRepository.findById(xcTask.getId());
if(optional.isPresent()){
return new ResponseResult(CommonCode.SUCCESS);
}
XcLearningCourse xcLearningCourse =
xcLearningCourseRepository.findXcLearningCourseByUserIdAndCourseId(userId, courseId);
if (xcLearningCourse == null) {//没有选课记录则添加
xcLearningCourse = new XcLearningCourse();
xcLearningCourse.setUserId(userId);
xcLearningCourse.setCourseId(courseId);
xcLearningCourse.setValid(valid);
xcLearningCourse.setStartTime(startTime);
xcLearningCourse.setEndTime(endTime);
xcLearningCourse.setStatus("501001");
xcLearningCourseRepository.save(xcLearningCourse);
} else {//有选课记录则更新日期
xcLearningCourse.setValid(valid);
xcLearningCourse.setStartTime(startTime);
xcLearningCourse.setEndTime(endTime);
xcLearningCourse.setStatus("501001");
xcLearningCourseRepository.save(xcLearningCourse);
}
//向历史任务表播入记录
Optional<XcTaskHis> optional = xcTaskHisRepository.findById(xcTask.getId());
if(!optional.isPresent()){
//添加历史任务
XcTaskHis xcTaskHis = new XcTaskHis();
BeanUtils.copyProperties(xcTask,xcTaskHis);
xcTaskHisRepository.save(xcTaskHis);
}
return new ResponseResult(CommonCode.SUCCESS);
} 


4.1.5 接收添加选课消息
接收到添加选课的消息调用添加选课方法完成添加选课,并发送完成选课消息。
com.xuecheng.learning.mq包下添加ChooseCourseTask
[AppleScript] 纯文本查看 复制代码
 @Component
public class ChooseCourseTask {
private static final Logger LOGGER = LoggerFactory.getLogger(ChooseCourseTask.class);
@Autowired
LearningService learningService;
@Autowired
RabbitTemplate rabbitTemplate;
/**
* 接收选课任务
*/
@RabbitListener(queues = {RabbitMQConfig.XC_LEARNING_ADDCHOOSECOURSE})
public void receiveChoosecourseTask(XcTask xcTask,Message message,Channel channel) throws
IOException {
LOGGER.info("receive choose course task,taskId:{}",xcTask.getId());
//接收到 的消息id
String id = xcTask.getId();
//添加选课
try {
String requestBody = xcTask.getRequestBody();
Map map = JSON.parseObject(requestBody, Map.class);
String userId = (String) map.get("userId");
String courseId = (String) map.get("courseId");
String valid = (String) map.get("valid");
Date startTime = null;
Date endTime = null;
SimpleDateFormat dateFormat = new SimpleDateFormat("YYYY‐MM‐dd HH:mm:ss");
if(map.get("startTime")!=null){
startTime =dateFormat.parse((String) map.get("startTime"));
}
if(map.get("endTime")!=null){
endTime =dateFormat.parse((String) map.get("endTime"));
}
//添加选课
ResponseResult addcourse = learningService.addcourse(userId, courseId,
valid,startTime, endTime,xcTask);
//选课成功发送响应消息
if(addcourse.isSuccess()){
//发送响应消息
rabbitTemplate.convertAndSend(RabbitMQConfig.EX_LEARNING_ADDCHOOSECOURSE,
RabbitMQConfig.XC_LEARNING_FINISHADDCHOOSECOURSE_KEY, xcTask );
LOGGER.info("send finish choose course taskId:{}",id);
}
} catch (Exception e) {
e.printStackTrace();
LOGGER.error("send finish choose course taskId:{}", id);
}
}
} 


4.2 订单服务结束任务
4.2.1 需求分析
订单服务接收MQ完成选课的消息,将任务从当前任务表删除,将完成的任务添加到完成任务表。
4.2.2 Dao
1、删除xc_task
2、添加xc_task_his
定义过程略
4.2.3 Service
TaskService中定义删除任务方法
[AppleScript] 纯文本查看 复制代码
 //删除任务
@Transactional
public void finishTask(String taskId){
Optional<XcTask> taskOptional = xcTaskRepository.findById(taskId);
if(taskOptional.isPresent()){
XcTask xcTask = taskOptional.get();
xcTask.setDeleteTime(new Date());
XcTaskHis xcTaskHis = new XcTaskHis();
BeanUtils.copyProperties(xcTask, xcTaskHis);
xcTaskHisRepository.save(xcTaskHis);
xcTaskRepository.delete(xcTask);
}
}


4.2.4 接收完成选课消息

com.xuecheng.manage_order.mq包下ChooseCourseTask类中添加receiveChoosecourseTask,接收完成选
课任务消息并进行处理。
[AppleScript] 纯文本查看 复制代码
 /**
* 接收选课响应结果
*/
@RabbitListener(queues = {RabbitMQConfig.xc_learning_finishaddchoosecourse})
public void receiveFinishChoosecourseTask(XcTask task,Message message, Channel channel) throws
IOException {
LOGGER.info("receiveChoosecourseTask...{}",task.getId());
//接收到 的消息id
String id = task.getId();
//删除任务,添加历史任务
taskService.finishTask(id);
}


4.3 集成测试
测试流程如下:
1、手动向任务表添加一条任务。
2、启动rabbitMQ.
3、启动订单服务、选课服务。
4、观察日志是否添加选课成功
完成任务后将xc_task任务移动到xc_task_his表中
完成任务后在选课表中多了一条学生选课记录
测试消息重复消费:
1、手动向任务表添加一条任务。
2、启动rabbitMQ.
3、先启动订单表,等待消息队列是否积累了多个消息。
4、再启动选课服务,观察是否重复添加选课


0 个回复

您需要登录后才可以回帖 登录 | 加入黑马