16-订单服务定时发送消息-乐观锁取任务

4.7 乐观锁取任务

考虑订单服务将来会集群部署,为了避免任务在1分钟内重复执行,这里使用乐观锁,实现思路如下:

  1. 每次取任务时判断当前版本及任务id是否匹配,如果匹配则执行任务,如果不匹配则取消执行。
  2. 如果当前版本和任务Id可以匹配到任务则更新当前版本加1.
    1、在Dao中增加校验当前版本及任务id的匹配方法
public interface XcTaskRepository extends JpaRepository<XcTask, String> {
//使用乐观锁方式校验任务id和版本号是否匹配,匹配则版本号加1
@Modifying
@Query("update XcTask t set t.version = :version+1 where t.id = :id and t.version =
:version")
public int updateTaskVersion(@Param(value = "id") String id,@Param(value = "version") int
version);
...

在这里插入图片描述

2、在service中增加方法,使用乐观锁方法校验任务

@Transactional
public int getTask(String taskId,int version){
int i = xcTaskRepository.updateTaskVersion(taskId, version);
return i;
}

在这里插入图片描述
报错
JPA事务问题Executing an update/delete query
如果JPA提示Executing an update/delete query,那是一定是因为Service层没有加@Transactional和再方法加@Modifying吧

在这里插入图片描述

3、执行任务类中修改

...
//任务id
String taskId = xcTask.getId();
//版本号
Integer version = xcTask.getVersion();
//调用乐观锁方法校验任务是否可以执行
if(taskService.getTask(taskId, version)>0){
//发送选课消息
taskService.publish(xcTask, xcTask.getMqExchange(),xcTask.getMqRoutingkey());
LOGGER.info("send choose course task id:{}",taskId);
}
...

在这里插入图片描述

测试(启动2个线程)

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
所以虽然2个进程,但是任务只能执行一次


版权声明:本文为minihuabei原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。