废话不多说,直接上代码,企业级拿来即用。
分布式锁组件共5个类,代码结构:
说明:
- RedissonConnector: 分布式锁客户端配置类。
- RedissonLocker: 分布式锁的工作类。
- RedissonLockWorker: 获取锁后的处理类。
- RedissonLockService: 分布式锁的接口类。
- RedissonLockException: 分布式锁异常类。
各个类详细内容:
-
package com.**.lock; import org.redisson.Redisson; import org.redisson.api.RedissonClient; import org.redisson.config.Config; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Component; import javax.annotation.PostConstruct; /** * @author yuan * redisson client连接类 */ @Component public class RedissonConnector { @Value("${redis.host}") private String host; @Value("${redis.port}") private String port; @Value("${redis.password}") private String password; private RedissonClient redissonClient; @PostConstruct public void init() { Config config = new Config(); config.useSingleServer().setAddress(host + ":" + port).setPassword(password); redissonClient = Redisson.create(config); } RedissonClient getRedissonClient() { return redissonClient; } }
-
package com.**.lock; import com.msunsoft.utils.RedistUtil; import org.redisson.api.RLock; import org.redisson.api.RedissonClient; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; import java.util.concurrent.TimeUnit; /** * @author yuan * redisson锁工作类 */ @Component public class RedissonLocker implements RedissonLockService { private final RedissonConnector connector; @Autowired public RedissonLocker(RedissonConnector connector) { this.connector = connector; } @Override public boolean lock(String sourceName) throws Exception { RLock rLock = this.getLock(RedistUtil.lock_prefix + sourceName); //尝试加锁,最多等待60秒,加锁lockTime以后自动解锁 return rLock.tryLock(60, RedistUtil.lock_expire, TimeUnit.SECONDS); } @Override public <T> T lock(String sourceName, RedissonLockWorker<T> worker) throws Exception { return lock(sourceName, worker, RedistUtil.lock_expire); } @Override public <T> T lock(String sourceName, RedissonLockWorker<T> worker, int lockTime) throws Exception { RLock rLock = this.getLock(RedistUtil.lock_prefix + sourceName); //尝试加锁,最多等待60秒,加锁lockTime以后自动解锁 boolean success = rLock.tryLock(60, lockTime, TimeUnit.SECONDS); if (success) { try { return worker.afterLockSuccess(); } finally { rLock.unlock(); } } throw new RedissonLockException(); } @Override public void unLock(String sourceName) { RLock rLock = this.getLock(RedistUtil.lock_prefix + sourceName); rLock.unlock(); } /** * 获取锁 */ private RLock getLock(String name) { RedissonClient client = connector.getRedissonClient(); return client.getLock(name); } }
-
package com.**.lock; /** * @author yuan * 获取锁后处理类 */ public interface RedissonLockWorker<T> { /** * 获取锁成功后执行业务逻辑 * @return 业务逻辑对象 * @throws Exception 异常信息 */ T afterLockSuccess() throws Exception; }
-
package com.**.lock; /** * @author yuan * 锁管理类 */ public interface RedissonLockService { /** * 加锁 * @param sourceName 资源名称 * @return 处理完业务逻辑后返回的数据 * @throws Exception 异常 */ boolean lock(String sourceName) throws Exception; /** * 加锁 * @param sourceName 资源名称 * @param worker 获取锁后工作类 * @return 处理完业务逻辑后返回的数据 * @throws Exception 异常 */ <T> T lock(String sourceName, RedissonLockWorker<T> worker) throws Exception; /** * 加锁 * @param sourceName 资源名称 * @param worker 获取锁后工作类 * @param lockTime 锁超时时间 * @return 处理完业务逻辑后返回的数据 * @throws Exception 异常 */ <T> T lock(String sourceName, RedissonLockWorker<T> worker, int lockTime) throws Throwable; /** * 锁释放 * @param sourceName 资源名称 */ void unLock(String sourceName); }
-
package com.**.lock; /** * @author yuan * 锁异常类 */ public class RedissonLockException extends RuntimeException { public RedissonLockException() { } public RedissonLockException(String message) { super(message); } }
-
@Autowired private RedissonLockService redissonLockService; @RequestMapping("/wechat/submitEvalInfo") public Result submitEvalInfo(@RequestBody List<QuestionnaireEvalDTO> evalList) throws Exception { TokenUser user = ThreadContext.get(); try { //sourceName随意,只要保证一定时间内唯一就行 return redissonLockService.lock(user.getLoginName() + "submitEvalInfo", () -> questionnaireService.submitEvalInfo(evalList, user)); } catch (UnsupportedEncodingException e) { return Result.fail("数据解码失败,请联系运营平台开发人员解决"); } }