Spring Redis Lock

Sonatype helps open source projects to set up Maven repositories on https://oss.sonatype.org/

License

License

Categories

Categories

Redis Data Databases
GroupId

GroupId

io.github.zhangcm
ArtifactId

ArtifactId

spring-redis-lock
Last Version

Last Version

0.1.1-RELEASE
Release Date

Release Date

Type

Type

jar
Description

Description

Spring Redis Lock
Sonatype helps open source projects to set up Maven repositories on https://oss.sonatype.org/
Source Code Management

Source Code Management

https://github.com/zhangcm/spring-redis-lock

Download spring-redis-lock

How to add to project

<!-- https://jarcasting.com/artifacts/io.github.zhangcm/spring-redis-lock/ -->
<dependency>
    <groupId>io.github.zhangcm</groupId>
    <artifactId>spring-redis-lock</artifactId>
    <version>0.1.1-RELEASE</version>
</dependency>
// https://jarcasting.com/artifacts/io.github.zhangcm/spring-redis-lock/
implementation 'io.github.zhangcm:spring-redis-lock:0.1.1-RELEASE'
// https://jarcasting.com/artifacts/io.github.zhangcm/spring-redis-lock/
implementation ("io.github.zhangcm:spring-redis-lock:0.1.1-RELEASE")
'io.github.zhangcm:spring-redis-lock:jar:0.1.1-RELEASE'
<dependency org="io.github.zhangcm" name="spring-redis-lock" rev="0.1.1-RELEASE">
  <artifact name="spring-redis-lock" type="jar" />
</dependency>
@Grapes(
@Grab(group='io.github.zhangcm', module='spring-redis-lock', version='0.1.1-RELEASE')
)
libraryDependencies += "io.github.zhangcm" % "spring-redis-lock" % "0.1.1-RELEASE"
[io.github.zhangcm/spring-redis-lock "0.1.1-RELEASE"]

Dependencies

compile (1)

Group / Artifact Type Version
org.springframework.boot : spring-boot-starter-data-redis jar 1.5.2.RELEASE

Project Modules

There are no modules declared in this project.

基于Spring Boot和Redis实现的一个分布式锁工具包,简化方法的加锁操作。

背景

在项目中使用redis作为分布式锁来控制并发时,经常会看到如下代码:

boolean locked = RedisUtil.tryLock(key);
try {
    if (locked) {
        // do business
    }
} finally {
    if (locked) {
        RedisUtil.unlock(key);
    }
}

这部分加锁的代码重复且冗余。如果项目中使用了JPA,并且上述代码包在一个带@Transaction的方法中,这部分代码还起不到加锁的作用。 为了简化开发,可以这部分代码作为aop代码抽取出来,就像Spring Transaction一样。

使用方法:

添加maven依赖:

<dependency>
    <groupId>io.github.zhangcm</groupId>
    <artifactId>spring-redis-lock</artifactId>
    <version>0.1.1-RELEASE</version>
</dependency>

在启动类加上@EnableLock注解,开启加锁功能

@SpringBootApplication
@EnableLock
@EnableAspectJAutoProxy(proxyTargetClass = true)
public class LockDemoApplication {

    public static void main(String[] args) {
        SpringApplication.run(LockDemoApplication.class, args);
    }
}

在需要加锁的方法上,添加@Lock,通过key属性可直接指定要锁的key

import com.justz.lock.annotation.Lock;
import org.springframework.stereotype.Service;

@Service
public class CountService {

    private int count = 0;

    @Lock(key = "count_lock")
    public void increWithLock() {
        count++;
    }

    public void increWithoutLock() {
        count++;
    }

    public int getCount() {
        return count;
    }

}

application.properties中添加redis配置:

spring.redis.host=127.0.0.1

测试用例:

@RunWith(SpringRunner.class)
@SpringBootTest
public class CountServiceTest {

    private static ExecutorService executorService = Executors.newFixedThreadPool(5);
    private int total = 500;

    @Autowired
    private CountService countService;

    @Test
    public void testAddWithoutLock() throws InterruptedException {
        execute(total, countService::increWithoutLock);
        Assert.assertEquals(total, countService.getCount());
    }

    @Test
    public void testAddWithLock() throws InterruptedException {
        execute(total, countService::increWithLock);
        Assert.assertEquals(total, countService.getCount());
    }

    private void execute(int total, Runnable runnable) throws InterruptedException {
        for (int i = 0; i < total; i++) {
            executorService.execute(runnable);
        }
        executorService.shutdown();
        while (!executorService.isTerminated()) {
            Thread.sleep(1000);
        }
    }
}

测试结果:

  • 第一个测试用例执行不通过,因为count++存在并发问题
  • 第二个测试用例执行通过,用锁来保证count++的顺序执行

特性

  • 自定义切入顺序。默认比@Transaction高1,确保在事务提交后再释放锁
  • 自定义key的生成规则,需实现KeyGenerator接口
  • 自定义锁的实现,需实现LockManager接口
  • 自定义注解

Versions

Version
0.1.1-RELEASE
0.1.0-RELEASE