Vividly understand the redis distributed lock and the logic to complete the timing order

The simplest code to lock on redis first

package com.van.mall.util;

import com.van.mall.common.RedisPool;
import redis.clients.jedis.Jedis;

/**
 * @author Van
 * @date 2020/3/25 - 15:39
 */
public class RedisLockUtil {
    public static Boolean lock(String key,String value){
        Jedis jedis= RedisPool.getJedis();
        if (jedis.setnx(key,value).intValue()==1){
            return true;//加锁成功
        }
        //现在还不能因为没取到锁就直接返回false,得判断这个锁是否过期。防止有线程死在里面没有解锁,后面的线程就永远拿不到锁了
        String lastTime=jedis.get(key);
        if (Long.valueOf(lastTime)<System.currentTimeMillis()){
            String lastTime2=jedis.getSet(key,value);
            //如果此时有两个线程同时判断了时间超时,并且到了要修改value这一步,这个判断保证了只能有一个线程获得锁
            //ps:后面getset的线程虽然拿不到锁了,但是它改了value,不过不要紧,这两个同时到达这里的线程。value不可能相差大于毫秒
            if (lastTime2.equals(lastTime)){
                return true;//加锁成功
            }
        }
        return false;
    }
    //传进来的key和value和加锁的时候传进来的key和value是一样的
    public static void unLock(String key,String value){
        Jedis jedis=RedisPool.getJedis();
        //获得redis中目前key对应的value,如果是加锁的这个线程set的,那么就有权限解锁
        //ps:防止死了的线程活过来,来了个解锁操作
        String MyTime=jedis.get(key);
        if (value.equals(MyTime)){
            jedis.del(key);
        }
    }
}

There are two methods, lock and unlock.
Image explanation:
lock:

A person (male 1) (there is a timer on hand, the value of the timer is the current time plus the timeout time, in milliseconds). To open the door (want to get the lock), he entered the key and value (the value of his timer) into the electronic device on the door (this action represents setnx).
In the first case, the door opened, and the key and value he set were recorded. (Thread gets locked) In the
second case, the door alarms and cannot be set. But he was not reconciled, so he opened the electronic screen on the door (it was dark before), took the key and got the value set by the last person (in fact, the two keys were passed in the same way), he recorded it with a notebook, and The current time comparison (this is the if statement that judges the timeout), (I will not talk about it if it has not timed out), and it turns out that it has timed out, so he is happily dancing, and at the same time in the parallel space-time The individual (male 2, here refers to another process or thread) and he judged that it has timed out at the same time, but male 2 quickly set his key value into it, and the returned value meets the requirements (the return value is equal to that set by the previous person Value) (here equivalent to getset), so male 2 opened the door and entered (acquired the lock). Going back to Man 1, I ’m happy, and now I ’m going to open the door. He executed getset. The result returned is not the value of the last person recorded in the book, but the value set by Man 2. So he realized that he himself He was preempted by someone who entered the judgment at the same time.

unlock:

Then above: At this time, Male 2 enters the gate, and the gate closes immediately. His value is recorded not only on the door, but also on the exit device (buried pen). He saw the last person died inside (if the lock was released without dying, there would be no timeout). No matter, he will do his task (execute the code between lock and unlock) within this time. But at this time the dead resurrected, he remembered his mission (he was about to release the lock), so he opened the electronic device of the exit and entered the value of the device on his hand, but he was surprised to find that the value set on the exit device Not consistent with his own value, so the door fails to open (release the lock) (here refers to the if statement in the unlock method).
At this time, Male 2 is finished, he can go to the export, and performs the same operation. The value recorded on his hand is the same as the value of the export, so he successfully opened the export (unlocked).

Closing order regularly:

I want to automatically delete the unpaid orders with a timeout of 30 minutes (in this logic, I need to increase the inventory and so on) to
simplify him to empty the trash.
I opened two tomcats. I hope that as long as there is one tomcat to perform the operation of emptying garbage, if you do not set up redis distributed locks, there will be two tomcats executing the close order task at the same time, which may cause data. Disorder and inconsistency.
So at this time, you can use it. The
first is to set a scheduled task with spring schedule. The
content is:
lock
executes the operation of emptying the trash can (close the order), if it is cleared, if it is not, it will not be
unlocked

Published 56 original articles · Like1 · Visits1509

Guess you like

Origin blog.csdn.net/weixin_44841849/article/details/105098348