Distributed Lock (five) - Based Distributed Lock redisson examples

Redisson Profile

Redisson is implemented on the basis of a Redis on Java in-memory data grid (In-Memory Data Grid). It not only provides a series of commonly used Java distributed object also provides a number of distributed services. redisson reference documentation . To some extent, he has enriched the redis data types, while the underlying network interactively using the NIO to further enhance the coordination of distributed relevant capacity.

More details about Redisson can be found in the above-mentioned document addresses posted. Redisson achieve distributed lock redis compared to a lot of convenience.

springboot introduced Redisson

1, the configuration of the introduction redisson

spring.redisson.address=redis://127.0.0.1:6379

Configuration needs to begin with redis, after all, in this period of redisson create source code

public static URI create(String uri) {
    URI u = URI.create(uri);
    // Let's assuming most of the time it is OK.
    if (u.getHost() != null) {
        return u;
    }
    String s = uri.substring(0, uri.lastIndexOf(":")).replaceFirst("redis://", "").replaceFirst("rediss://", "");
    // Assuming this is an IPv6 format, other situations will be handled by
    // Netty at a later stage.
    return URI.create(uri.replace(s, "[" + s + "]"));
}

Clearly see here the string processing time will be cut off at the beginning or the beginning of redis rediss, if no exception is thrown.

2, the redisson to container management

/**
 * redisson的分布式客户端
 * @return
 */
@Bean
public RedissonClient redissonClient(){
    Config config = new Config();
    config.useSingleServer().setAddress(env.getProperty("spring.redisson.address"));
    RedissonClient client = Redisson.create(config);
    return client;
}

This configuration will have to bean annotated class hosting. And return RedissonClient (in fact, can be returned directly Redisson)

Introducing redisson, various packaging operations

package com.learn.lockservce.component;

import lombok.extern.slf4j.Slf4j;
import org.redisson.Redisson;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

/**
 * autor:liman
 * createtime:2020/1/30
 * comment: Redisson的分布式锁组件。
 */
@Component
@Slf4j
public class RedissonLockComponent implements InitializingBean {

    @Autowired
    private RedissonClient redissonClient;

    private static Redisson redisson;

    //注入后的属性设置方法,这里其实有点稍微多此一举,可以直接在容器托管的时候就返回Redisson就行。
    public void afterPropertiesSet() throws Exception {
        redisson = (Redisson) redissonClient;
    }

    /**
     * 获取锁
     * @param lockName
     * @return
     */
    public RLock acquireLock(String lockName){
        RLock lock = redisson.getLock(lockName);
        lock.lock();
        return lock;
    }

    /**
     * 释放锁
     * @param lock
     */
    public void releaseLock(RLock lock){
        lock.unlock();
    }
}

Here encapsulates acquire and release locks operation, while by implementing the method afterProperties InitializingBean interface, complete conversion of the forced type. Here again Incidentally, the source code can be seen Redisson is an implementation of RedissonClient.

Here Insert Picture Description

The same business process

/**
 * 基于Redisson分布式锁
 * @param productLockDto
 * @return
 */
@Transactional(rollbackFor = Exception.class)
public int updateStockRedisson(ProductLockDto productLockDto){
    int res = 0;
    boolean flag = true;
    while(flag){
		//获取分布式锁。
        RLock rLock = redissonLockComponent.acquireLock(String.valueOf(productLockDto.getId()));
        try{
            if(rLock!=null){
				//真正的业务处理
                flag=false;
                ProductLock productLockEntity = lockMapper.selectByPrimaryKey(productLockDto.getId());
                int leftStock = productLockEntity.getStock();
                if(productLockEntity!=null && productLockEntity.getStock().compareTo(productLockDto.getStock())>=0){
                    productLockEntity.setStock(productLockDto.getStock());
                    res = lockMapper.updateStockForNegative(productLockEntity);
                    if(res>0){
                        log.info("基于redisson获取分布式锁成功,剩余stock:{}",leftStock-1);
                    }
                }
            }
        }catch (Exception e){
			//异常处理之后,继续获取锁
            log.error("获取锁异常,{}",e.fillInStackTrace());
            flag=true;
        }finally {
			//正确释放锁
            if(rLock!=null){
                redissonLockComponent.releaseLock(rLock);
                flag=false;
            }
        }
    }
    return res;
}

And several blog before, the same business logic, the same body of code, the same idea here is not summed up, it appears that in general are like wheels

/**
 * 基于Redisson分布式锁
 * @param productLockDto
 * @return
 */
@Transactional(rollbackFor = Exception.class)
public int updateStockRedisson(ProductLockDto productLockDto){
    int res = 0;
    boolean flag = true;
    while(flag){
		//获取分布式锁。
        RLock rLock = redissonLockComponent.acquireLock(String.valueOf(productLockDto.getId()));
        try{
            if(rLock!=null){
				//真正的业务处理
                
            }
        }catch (Exception e){
			//异常处理之后,继续获取锁
            log.error("获取锁异常,{}",e.fillInStackTrace());
            flag=true;
        }finally {
			//正确释放锁
            
        }
    }
    return res;
}

to sum up

So far, several simple examples on distributed lock, summed complete details, see the following:

Distributed Lock (a) - example of the basic environmental structures .

Distributed Lock (II) - Based Distributed Lock database instance .

Distributed Lock (c) - examples of the redis based Distributed Lock .

Distributed Lock (four) - Based Distributed Lock instance of zookeeper .

Published 125 original articles · won praise 35 · views 80000 +

Guess you like

Origin blog.csdn.net/liman65727/article/details/104113038