Git Product home page Git Product logo

spring-boot2-learning's Issues

请问在并发下适用吗?

你好,我是一位JAVA初学者,也刚刚接触spring不久,同时也在多线程方面进行探索,发现你在key生成时,使用 StringBuilder 这个是出于速度方面考虑的吗。

chapter22 轻松搞定重复提交(分布式锁) 中的BUG

你好,非常喜欢您的分享,在运行chapter22一章的demo时发现了两个问题,不知道是不是遗留的bug,如理解有问题,请指正😄

  1. LockMethodInterceptor.java
@Around("execution(public * *(..)) && @annotation(com.battcn.annotation.CacheLock)")
    public Object interceptor(ProceedingJoinPoint pjp) {
        MethodSignature signature = (MethodSignature) pjp.getSignature();
        Method method = signature.getMethod();
        CacheLock lock = method.getAnnotation(CacheLock.class);
        if (StringUtils.isEmpty(lock.prefix())) {
            throw new RuntimeException("lock key don't null...");
        }
        final String lockKey = cacheKeyGenerator.getLockKey(pjp);
        String value = UUID.randomUUID().toString();
        try {
            // 假设上锁成功,但是设置过期时间失效,以后拿到的都是 false
            final boolean success = redisLockHelper.lock(lockKey, value, lock.expire(), lock.timeUnit());
            if (!success) {
                throw new RuntimeException("重复提交");
            }
            try {
                return pjp.proceed();
            } catch (Throwable throwable) {
                throw new RuntimeException("系统异常");
            }
        } finally {
            // TODO 如果演示的话需要注释该代码;实际应该放开
            redisLockHelper.unlock(lockKey, value);
        }
    }

这里的String value = UUID.randomUUID().toString();是不是有多线程问题,当第一个线程未处理完,第二个线程运行到这里是会刷新value,导致第一个线程unlock时会使用第二个线程的value

  1. RedisLockHelper.java
public boolean lock(String lockKey, final String uuid, long timeout, final TimeUnit unit) {
        final long milliseconds = Expiration.from(timeout, unit).getExpirationTimeInMilliseconds();
        boolean success = stringRedisTemplate.opsForValue().setIfAbsent(lockKey, (System.currentTimeMillis() + milliseconds) + DELIMITER + uuid);
        if (success) {
            stringRedisTemplate.expire(lockKey, timeout, TimeUnit.SECONDS);
        } else {
           // 这里直接更新这个值是不是有点问题,应该判断时间,超时再更新
            String oldVal = stringRedisTemplate.opsForValue().getAndSet(lockKey, (System.currentTimeMillis() + milliseconds) + DELIMITER + uuid);
            final String[] oldValues = oldVal.split(Pattern.quote(DELIMITER));
            if (Long.parseLong(oldValues[0]) + 1 <= System.currentTimeMillis()) {
                return true;
            }
        }
        return success;
    }

我认为这里应该这样写

public boolean lock(String lockKey, final String uuid, long timeout, final TimeUnit unit) {
        final long milliseconds = Expiration.from(timeout, unit).getExpirationTimeInMilliseconds();
        boolean success = stringRedisTemplate.opsForValue().setIfAbsent(lockKey, (System.currentTimeMillis() + milliseconds) + DELIMITER + uuid);
        if (success) {
            stringRedisTemplate.expire(lockKey, timeout, TimeUnit.SECONDS);
        } else {
            String oldVal = stringRedisTemplate.opsForValue().get(lockKey);
            final String[] oldValues = oldVal.split(Pattern.quote(DELIMITER));
            if (Long.parseLong(oldValues[0]) + 1 <= System.currentTimeMillis()) {
                stringRedisTemplate.opsForValue().set(lockKey, (System.currentTimeMillis() + milliseconds) + DELIMITER + uuid);
                return true;
            }
        }
        return success;
    }

如理解有问题请指正😄

bean of type RedisTemplate could not be found

private RedisTemplate<String, Serializable> limitRedisTemplate;

@Autowired
public LimitInterceptor(RedisTemplate<String, Serializable> limitRedisTemplate) {
    this.limitRedisTemplate = limitRedisTemplate;
}

请问一下,这个地方 的代码是不是有问题?
报错:
required a bean of type 'org.springframework.data.redis.core.RedisTemplate' that could not be found.

轻松搞定重复提交

标题内容都不符合,
引用原文“在平时开发中,如果网速比较慢的情况下,用户提交表单后,发现服务器半天都没有响应,那么用户可能会以为是自己没有提交表单,就会再点击提交按钮重复提交表单,我们在开发中必须防止表单重复提交….“

内容写的是无法实现防止个人重复提交,直接干死了这个功能就一个人同时可以使用。

说你几句内容与标题不符,还删除好友。

你这个人调子高什么呀,一般的博客我懒得联系改正,看你辛苦,分享,友情提醒你,你就上天了。

做技术的人,不要不愿意听别人的,自己错了,就是错了。

不愿意接受别人提出的问题,自己成不了什么大人物。

关于锁的释放

博主你好,小弟有些不解,按理一个请求过来,请求结束后应该释放掉该锁。可是看到代码里是在finally里调用了锁的释放,这个应该怎么理解呢?抛出重复提交的异常也要释放该锁吗?这部分理解不了啊!求教。

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.