在 Spring Boot 项目中,实现分布式锁可以通过多种方式,常见的有使用 Redis、数据库等。以下是通过 Redis 和数据库两种方式来实现分布式锁的示例。
1、使用 Redis 实现分布式锁
Redis 提供了简单且高效的分布式锁机制。可以使用 SETNX
命令(setIfAbsent()
)来实现锁的获取和释放。
锁类
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;import java.util.concurrent.TimeUnit;@Component
public class RedisLock {private final RedisTemplate<String, String> redisTemplate;public RedisLock(RedisTemplate<String, String> redisTemplate) {this.redisTemplate = redisTemplate;}public boolean acquireLock(String lockKey, long timeout, TimeUnit unit) {Boolean success = redisTemplate.opsForValue().setIfAbsent(lockKey, "locked");if (Boolean.TRUE.equals(success)) {redisTemplate.expire(lockKey, timeout, unit);}return success != null && success;}public void releaseLock(String lockKey) {redisTemplate.delete(lockKey);}
}
使用示例
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;@RestController
public class LockController {@Autowiredprivate RedisLock redisLock;@GetMapping("/critical-section")public String criticalSection() {String lockKey = "my_lock";if (redisLock.acquireLock(lockKey, 10, TimeUnit.SECONDS)) {try {// 业务逻辑} finally {redisLock.releaseLock(lockKey);}} else {return "没有获取到锁,资源正在使用。";}}
}
2、使用数据库实现分布式锁
如果使用关系型数据库,可以通过表记录来实现分布式锁。
创建锁表
CREATE TABLE distributed_lock (lock_name VARCHAR(255) PRIMARY KEY,locked BOOLEAN NOT NULL,lock_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
锁类
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Component;@Component
public class DatabaseLock {private final JdbcTemplate jdbcTemplate;public DatabaseLock(JdbcTemplate jdbcTemplate) {this.jdbcTemplate = jdbcTemplate;}public boolean acquireLock(String lockName) {int rowsAffected = jdbcTemplate.update("INSERT INTO distributed_lock (lock_name, locked) VALUES (?, ?)", lockName, true);return rowsAffected > 0;}public void releaseLock(String lockName) {jdbcTemplate.update("DELETE FROM distributed_lock WHERE lock_name = ?", lockName);}
}
使用示例
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;@RestController
public class LockController {@Autowiredprivate DatabaseLock databaseLock;@GetMapping("/critical-section")public String criticalSection() {String lockName = "my_lock";if (databaseLock.acquireLock(lockName)) {try {// 业务逻辑} finally {databaseLock.releaseLock(lockName);}} else {return "没有获取到锁,资源正在被使用。";}}
}
Redis 通常更适用于高性能的分布式环境,而数据库锁更容易集成到已有的数据库系统中。