Idempotent

49 阅读1分钟

1。redis 存储idempotentModel 数据

model:

@RedisHash(value = "idm")
@Data
public class IdempotentModel implements Serializable {
    private static final long serialVersionUID = 1L;



    @Id
    String id;


    @Indexed
    String state;

    String message;

    int version;

    @CreatedDate
    Date ctime;

    @LastModifiedDate
    Date utime;

}
  1. insert model
if (redisTemplate.opsForHash().putIfAbsent("idm:12", "id", "12")) {
   save = idempotentJpa.save(model);
    log.info("ok");
}
  1. version add :
Long version = redisTemplate.opsForHash().increment("idm:" + model.getId(), "version", 1);
  1. version add 2
var updateVersionScript = new DefaultRedisScript();
updateVersionScript.setScriptSource(new ResourceScriptSource(new ClassPathResource("luascript/updateVersion.lua")));
updateVersionScript.setResultType(Boolean.class);

ObjectMapper om = new ObjectMapper();
// 解决查询缓存转换异常的问题
om.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);
om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
// 支持 jdk 1.8 日期   ---- start ---
om.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);
om.registerModule(new Jdk8Module())
        .registerModule(new JavaTimeModule())
        .registerModule(new ParameterNamesModule());
// --end --
GenericJackson2JsonRedisSerializer  serializer = new GenericJackson2JsonRedisSerializer(om);

redisTemplate.setHashValueSerializer(serializer);
redisTemplate.setHashKeySerializer(RedisSerializer.string());
redisTemplate.setKeySerializer(RedisSerializer.string());
redisTemplate.setValueSerializer(serializer);
IdempotentModel model = idempotentJpa.findById(id).orElse(null);


Boolean result = (Boolean) redisTemplate.execute(updateVersionScript, List.of("idm:" + model.getId()) ,model.getVersion() , model.getVersion() + 1, LocalDateTime.now());

lua:

-- update version

local  idempotentId   = KEYS[1]
local  OldVersion  = tonumber(ARGV[1])
local  newVersion = tonumber(ARGV[2])
local  utime = ARGV[3]
local result_1 = tonumber(redis.call('hget', idempotentId, 'version'))

if result_1 ==  OldVersion
then
  redis.call('hset', idempotentId, 'version', newVersion, 'utime', utime)
return 1
else
return 0
end;
  1. updatebyid and state
Boolean result = (Boolean) redisTemplate.execute(updateVersionScript, List.of("idm:" + id) ,"haha wo shi ni baba " , "success", LocalDateTime.now());

lua


local  idempotentId   = KEYS[1]
local  message  = ARGV[1]
local  state = ARGV[2]
local  utime = ARGV[2]
local result_1 = redis.call('hget', idempotentId, 'state')

if result_1 ==  'run'
then
  redis.call('hset', idempotentId, 'message', message, 'state', state, 'utime', utime)
  return 1
else
return 0
end;