增加分布式锁解决多用户同时操作排序情况下序号混乱的问题。

master
rong.liu 2 years ago
parent ff46f472ca
commit c16f137dc6
  1. 7
      src/main/java/com/huoran/iasf/controller/SysContentController.java
  2. 108
      src/main/java/com/huoran/iasf/service/impl/SysContentServiceImpl.java

@ -90,7 +90,10 @@ public class SysContentController {
queryWrap.eq("column_id", sysContent.getColumnId());
queryWrap.eq("deleted", 1);
Integer count = service.count(queryWrap);
sysContent.setSequence(count++);
if (count == 0) {
count = 1;
}
sysContent.setSequence(count + 1);
boolean addState = service.save(sysContent);
@ -265,7 +268,6 @@ public class SysContentController {
public R modifiedSort(
@ApiParam(name = "sequenceNumber", value = "要排序的序号", required = true) @RequestParam Integer sequenceNumber,
@ApiParam(name = "articleId", value = "文章Id", required = true) @RequestParam Integer articleId) {
return service.modifiedSort(sequenceNumber, articleId);
}
@ -293,6 +295,7 @@ public class SysContentController {
QueryWrapper<SysContent> queryWrap1 = new QueryWrapper<>();
queryWrap1.eq("column_id", columnId);
queryWrap1.eq("deleted", 1);
queryWrap1.orderByDesc("release_time");
List<SysContent> list = service.list(queryWrap1);
Integer count = 0;

@ -14,11 +14,15 @@ import com.huoran.iasf.vo.req.ArticleModifiedSortReq;
import com.huoran.iasf.vo.req.ContentHeavyTitleReqVO;
import com.huoran.iasf.vo.req.PageContentReqVO;
import com.huoran.iasf.vo.resp.PageContentRespVO;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.beans.factory.annotation.Autowired;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.*;
import java.util.concurrent.TimeUnit;
/**
* @描述文章管理 服务类
@ -28,6 +32,7 @@ import java.util.*;
@Service
public class SysContentServiceImpl extends ServiceImpl<SysContentMapper, SysContent> implements SysContentService {
private final static Logger logger = LoggerFactory.getLogger(SysContentServiceImpl.class);
@Autowired
private SysContentMapper mapper;
@ -148,61 +153,128 @@ public class SysContentServiceImpl extends ServiceImpl<SysContentMapper, SysCont
@Override
public R modifiedSort(Integer sequenceNumber, Integer articleId) {
// 占分布式锁,去redis占坑
// 1. 分布式锁占坑
Boolean lock = redisTemplate.opsForValue().setIfAbsent("articleSortLock", "value", 30, TimeUnit.SECONDS);
if (lock) {
//加锁成功...
if (sequenceNumber <= 0) {
redisTemplate.delete("articleSortLock"); //删除key,释放锁
return R.fail("请输入正确的序号!");
}
SysContent content = baseMapper.selectById(articleId);
//获取当前排序的序号
Integer currentSerialNumber = content.getSequence();
//获取当前文章所属栏目id
Integer columnId = content.getColumnId();
//获取栏目下全部文章的数量与当前输入的序号判断 如果要更改的序号大于当前有的数量,直接替换
QueryWrapper<SysContent> queryWrapper = new QueryWrapper<>();
queryWrapper.eq("column_id", columnId);
queryWrapper.eq("deleted", 1);
List<SysContent> contentList = baseMapper.selectList(queryWrapper);
if (sequenceNumber >= contentList.size()) {
sequenceNumber = contentList.size();
}
if (currentSerialNumber.equals(sequenceNumber)) {
redisTemplate.delete("articleSortLock"); //删除key,释放锁
return R.success();
}
//修改当前序号
UpdateWrapper<SysContent> updateWrapper = new UpdateWrapper<>();
updateWrapper.set("sequence", sequenceNumber);
updateWrapper.eq("id", articleId);
baseMapper.update(new SysContent(), updateWrapper);
//做乐观锁处理
updateWrapper.eq("sequence", currentSerialNumber);
int updateCount = baseMapper.update(new SysContent(), updateWrapper);
UpdateWrapper<SysContent> updateWrapper1 = new UpdateWrapper<>();
updateWrapper1.ne("id", articleId);
// 序号越小值越算大
//currentSerialNumber 当前文章的序号
//sequenceNumber 要更改的序号
/**
* 就要判断排序是值改小还是改大
* 大改小比如53改5那就加一个语句大于等于5并且小于53
* 如果是小改大比如3改50那就是大于3并且小于等于50"
*/
if (currentSerialNumber > sequenceNumber) {
//改大 gt >
updateWrapper1.setSql(" sequence = sequence + 1");
updateWrapper1.last(" and sequence >= " + sequenceNumber + " and sequence < " + currentSerialNumber);
} else if (currentSerialNumber < sequenceNumber) {
//改小
updateWrapper1.le("sequence", sequenceNumber);
//le为<=
// updateWrapper1.le("sequence", sequenceNumber);
updateWrapper1.setSql(" sequence = sequence - 1");
updateWrapper1.last(" and sequence > " + currentSerialNumber + " and sequence <= " + sequenceNumber);
//用于判断序号为本身就为1时候就不减了
updateWrapper1.ne("sequence", 1);
// updateWrapper1.ne("sequence", 1);
}
updateWrapper1.eq("column_id", columnId);
updateWrapper1.eq("deleted", 1);
baseMapper.update(new SysContent(), updateWrapper1);
redisTemplate.delete("articleSortLock"); //删除key,释放锁
return R.success();
} else {
return R.fail("当前有用户操作排序,请稍后刷新重试!");
}
}
/*@Override
public R modifiedSort(Integer newIndex, Integer articleId,Integer sort) {
if (newIndex <= 0) {
return R.fail("请输入正确的序号!");
}
//获取当前排序的序号
SysContent content = baseMapper.selectById(articleId);
//获取当前文章所属栏目id
Integer columnId = content.getColumnId();
//查看当前升序情况下全部文章信息
QueryWrapper<SysContent> queryWrapper = new QueryWrapper<>();
queryWrapper.eq("column_id", columnId);
queryWrapper.eq("deleted", 1);
if (sort==0){
queryWrapper.orderByAsc("sequence");
}else if (sort==1){
queryWrapper.orderByDesc("sequence");
}
List<SysContent> contentList = baseMapper.selectList(queryWrapper);
//获取当前序号在list中的顺序
int currentIndex = contentList.indexOf(content);
//获取当前排序的序号
Integer currentSerialNumber = content.getSequence();
if (currentIndex == -1) {
// 文章不存在,不做任何操作
return R.success();
}
//对于传过来的序号 处理用于匹配集合的下标
if (currentSerialNumber > newIndex) {
newIndex--;
}else {
newIndex++;
}
if (currentIndex == newIndex) {
// 新旧位置相同,不做任何操作
return R.success();
}
// 移除当前位置的文章
contentList.remove(content);
if (newIndex >= contentList.size()) {
// 插入到末尾
contentList.add(content);
} else {
// 插入到新位置
contentList.add(newIndex, content);
}
for (int i = 0; i < contentList.size(); i++) {
SysContent article = contentList.get(i);
article.setSequence(i + 1);
baseMapper.updateById(article);
}
return R.success();
}*/
}

Loading…
Cancel
Save