测试阶段,由于存在某一功能的同时操作,该功能还是入库逻辑,此时若不进行处理,会造成插入表中多条重复数据,为此该问题需要修复。
在接口开始进行对是否存在某个key值的判断,若不存在,则插入一条到redis中并加锁;若存在,则提示“正在处理中”;若中间出现逻辑处理异常,则需要对该key值删除;最后进行对锁的释放;
- <dependency>
- <groupId>org.springframework.bootgroupId>
- <artifactId>spring-boot-starter-data-redisartifactId>
- dependency>
- redis:
- host: 127.0.0.1
- port: 6379
- timeout: 10
- poolMaxTotal: 1000
- poolMaxIdle: 500
- poolMaxWait: 500
- import com.example.demo.entity.User;
-
- import org.apache.ibatis.annotations.Mapper;
-
- @Mapper
- public interface UserMapper {
-
- int add(User user);
-
- User queryByName(String name);
- }
- "1.0" encoding="utf-8"?>
- mapper
- PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
- "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
- <mapper namespace="com.example.demo.mapper.UserMapper">
- <select id="queryByName" resultMap="userResult">
- select id,name,age from "USER"
- where name=#{name}
- select>
-
- <insert id="add" parameterType="com.example.demo.entity.User">
- INSERT INTO "USER" (id,name, age)
- VALUES (SYS_GUID(),#{name},#{age})
- insert>
- mapper>
- import org.springframework.beans.factory.annotation.Autowired;
- import org.springframework.data.redis.core.RedisTemplate;
- import org.springframework.stereotype.Service;
-
- import java.util.concurrent.TimeUnit;
-
-
- @Service
- public class RedisService {
-
- @Autowired
- RedisTemplate
redisTemplate; -
- /**
- * 加锁
- * @param key
- * @param value
- * @param expireTime
- * @return
- */
- public boolean lock(String key, String value, Long expireTime) {
- Boolean success = redisTemplate.opsForValue().setIfAbsent(key, value);
- if (expireTime != null && expireTime > 0) {
- redisTemplate.expire(key, expireTime, TimeUnit.SECONDS);
- }
- return success != null && success;
- }
-
- /**
- * 释放锁
- * @param key
- */
- public void unlock(String key) {
- redisTemplate.opsForValue().getOperations().delete(key);
- }
-
- /**
- * 根据key删除信息
- * @param key
- */
- public void deleteStr(String key) {
- redisTemplate.delete(key);
- }
- }
-
- @Bean
- @SuppressWarnings("all")
- public RedisTemplate
redisTemplate(RedisConnectionFactory factory) { - RedisTemplate
template = new RedisTemplate(); - template.setConnectionFactory(factory);
- Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class);
- ObjectMapper om = new ObjectMapper();
- om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
- om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
- jackson2JsonRedisSerializer.setObjectMapper(om);
- StringRedisSerializer stringRedisSerializer = new StringRedisSerializer();
- // key采用String的序列化方式
- template.setKeySerializer(stringRedisSerializer);
- // hash的key也采用jackson的序列化方式
- template.setHashKeySerializer(jackson2JsonRedisSerializer);
- // value序列化方式采用jackson
- template.setValueSerializer(jackson2JsonRedisSerializer);
- // hash的value序列化方式采用jackson
- template.setHashValueSerializer(jackson2JsonRedisSerializer);
- template.afterPropertiesSet();
- return template;
- }
该程序对新增用户功能同时操作的模拟,补充redis中key的判断,具体开发逻辑或内容可以视情况而定!
- import com.example.demo.entity.User;
- import com.example.demo.mapper.UserMapper;
- import org.slf4j.Logger;
- import org.slf4j.LoggerFactory;
- import org.springframework.beans.factory.annotation.Autowired;
- import org.springframework.web.bind.annotation.PostMapping;
- import org.springframework.web.bind.annotation.RequestBody;
- import org.springframework.web.bind.annotation.RequestMapping;
- import org.springframework.web.bind.annotation.RestController;
- import com.example.demo.service.RedisService;
-
- import java.util.List;
-
- @RestController
- @RequestMapping("/user")
- public class UserController {
-
- private static final Logger logger = LoggerFactory.getLogger(UserController.class);
-
- @Autowired
- private UserMapper userMapper;
-
- @Autowired
- private RedisService redisService;
-
- @PostMapping("/addTest")
- public void addTest(@RequestBody User user) throws Exception {
-
- //todo 该功能的状态校验
- //1.判断该用户在redis是否存在
- if (!redisService.lock("addUser", String.valueOf(System.currentTimeMillis()), 15L)) {
- throw new Exception("正在操作中");
- }
- try {
- //2.逻辑处理
- User user1 = userMapper.queryByName(user.getName());
- if (user1 != null) {
- throw new Exception("该用户" + user.getName() + "已存在!");
- }
- for (int i = 0; i < 1000; i++) {
- for (int j = 0; j < 1000; j++) {
- logger.info("i*j={}", i * j);
- }
- }
- userMapper.add(user);
- } catch (Exception e) {
- redisService.deleteStr("addUser");
- throw e;
- } finally {
- redisService.unlock("addUser");
- }
- }
- }
一用户信息操作结果:

另一用户操作结果:

等待2分钟,该用户继续操作该数据,会提示“该用户已存在!”
