步骤:
1、引入依赖

<dependency>
<groupId>org.redisson</groupId>
<artifactId>redisson</artifactId>
<version>3.13.2</version>
</dependency>

 

2、redisLock配置

yaml配置:

spring:
  redis:
  database: 0
  host: localhost
  port: 6379
  timeout: 3600
  password: 123456

(注:redis未设置password时请注释掉)

redis配置属性绑定:

@Data
@Component
@ConfigurationProperties(prefix = "spring.redis")
public class RedisProperties {

private Integer database;

private String host;

private Integer port;

private String password;

private Integer timeout;

 

redisson实例配置

@Configuration
@EnableConfigurationProperties(RedisProperties.class)
public class ApiConfig {

  @Bean
  public RedissonClient redisClient(RedisProperties redisProperties) {
    Config config = new Config();
    String address = "redis://".concat(redisProperties.getHost()).concat(":")
      .concat(redisProperties.getPort().toString());
    config.useSingleServer()
      .setAddress(address)
      .setDatabase(redisProperties.getDatabase())
      .setPassword(redisProperties.getPassword());
    return Redisson.create(config);
  }
}

 


3、创建RedisLockService类

创建 SampleCallback 接口

public interface SampleCallback<T> {

/**
* 执行
*
* @return T
*/
T execute();
}

创建 RedisLockService 类

@Service
public class RedisLockService {

@Autowired
private RedissonClient redissonClient;

/***
* 可重入锁(Reentrant Lock)
*
* Redisson内部提供了一个监控锁的看门狗,它的作用是在Redisson实例被关闭前,不断的延长锁的有效期。
* 默认情况下,看门狗检查锁的超时时间是30秒钟,也可以通过修改Config.lockWatchdogTimeout来另行指定。
*
* @param key 被加锁的key
* @param action action
* @return T
* @author qs
* @date 2020/7/10 13:38
* @since 1.0.0
*/
public <T> T redisSynchronized(String key, SampleCallback<T> action) {
// 获取指定key的锁实例
RLock lock = redissonClient.getLock(key);
try {
// 加锁,并指定锁过期释放时间
lock.lock(35, TimeUnit.SECONDS);
// 执行并返回操作结果
return action.execute();
} finally {
// 释放锁
lock.unlock();
}
}
}

 

4、创建测试服务

@Service
public class AccountServiceImpl implements AccountService {
public boolean reducedBalance(Integer uid, Integer number) {
return redisLockService.redisSynchronized(RedisKeys.REDIS_LOCK_KEY_PREFIX + uid, () -> {
Account account = accountMapper.selectByPrimaryKey(uid);

int updateCount = 0;
Integer balance = account.getBalance();
if (Objects.nonNull(balance) && balance > Constant.ZERO && account.getBalance() >= number) {
account.setBalance(account.getBalance() - number);

updateCount = accountMapper.updateByPrimaryKeySelective(account);
}

return updateCount > 0;
});
}
}

 

Account实体类

@Data
@Table(name = "account")
public class Account {

  @Id
  @GeneratedValue(generator = "JDBC")
  private Integer uid;

  /**
   * 用户名
   */
  private String username;

  /**
   * 密码
   */
  private String password;

  /**
   * 是否有效(0.有效 1.无效)
   */
  private Short valid;

  /**
   * 余额(单位:分)
   */
  private Integer balance;
View Code