目录(?)[+]

 

分布式锁一般有三种实现方式:

  1. 数据库乐观锁;

  2. 基于Redis的分布式锁;

  3. 基于ZooKeeper的分布式锁。本篇博客将介绍第二种方式,基于Redis实现分布式锁。虽然网上已经有各种介绍Redis分布式锁实现的博客,然而他们的实现却有着各种各样的问题,为了避免误人子弟,本篇博客将详细介绍如何正确地实现Redis分布式锁。

可靠性

  首先,为了确保分布式锁可用,我们至少要确保锁的实现同时满足以下四个条件:

  互斥性。在任意时刻,只有一个客户端能持有锁。

  不会发生死锁。即使有一个客户端在持有锁的期间崩溃而没有主动解锁,也能保证后续其他客户端能加锁。

  具有容错性。只要大部分的Redis节点正常运行,客户端就可以加锁和解锁。

  解铃还须系铃人。加锁和解锁必须是同一个客户端,客户端自己不能把别人加的锁给解了。

使用StackExchange.Redis 实现起来简单得很

/// <summary>
/// 加锁,如果锁定成功,就去执行方法
/// </summary>
public static bool LockTake(string key, string data, int seconds, int db = 0)
{
// key:用key来当锁,因为key是唯一的。
// value:很多童鞋可能不明白,有key作为锁不就够了吗,为什么还要用到value?原因就是我们在上面讲到可靠性时,
// 分布式锁要满足第四个条件解铃还须系铃人,通过给value赋值为Guid.NewGuid().ToString(),我们就知道这把锁是哪个请求加的了,在解锁的时候就可以有依据。
return GetDatabase(db).LockTake(key, data, (DateTime.Now.AddSeconds(seconds) - DateTime.Now));
} /// <summary>
/// 解锁
/// </summary>
public static bool LockRelease(string key, string data, int db = 0)
{
return GetDatabase(db).LockRelease(key, data);
}

调用实现

string guid = Guid.NewGuid().ToString();
if (RedisHelper.LockTake(wechatOpenId, guid, 90, 15))
{
try
{
// 执行方法
}
catch (Exception e)
{
// 异常
}
finally
{
RedisHelper.LockRelease(wechatOpenId, guid, 15);
}
}
else {
// 已锁,无法执行
return null;
}

Ruthless https://notes.clump.cc/technology/3348

 
分类: NoSQL

最新文章

  1. c语言第一章第一节 认识变量
  2. python之路十三
  3. ORM数据层框架的设计热点:更新指定的列的几种设计方案
  4. struts-标签
  5. sqlmap笔记本
  6. python3内置函数详解
  7. Hadoop-2.6.0 集群的 安装与配置
  8. [Solution] 一步一步WCF(1) 快速入门
  9. Opencv 摄像头矫正
  10. 使用头文件climits中的符号常量获知整型数据的表数范围---gyy整理
  11. 转载ASP.NET MVC 和ASP.NET Web Form简单区别
  12. yiiwheels.widgets.datetimepicker.WhDateTimePicker language
  13. 基于AGS JS开发自定义贴图图层
  14. Android 使用gradle版本冲突
  15. bzoj 3122 随机数生成器 - BSGS
  16. (mysql)触发器、事件、事务、函数
  17. Winform无边框窗体拖动
  18. 高性能流媒体服务器EasyDarwin
  19. 图解JVM内存分配和回收
  20. FPGA千兆网UDP协议实现

热门文章

  1. 配置/更改vue项目中的资源路径
  2. python基础语法9 生成器,面向对象编程思想,三元表达式,列表生成式,生成器表达式(生成式),匿名函数,内置函数
  3. Linux 防火墙 | Linux 服务器如何开放端口 配置防火墙
  4. GAME-BASED LEARNING
  5. 重温Elasticsearch
  6. 主语,that和which
  7. 关于golang-mod的使用方法
  8. Spring整合MyBatis整合
  9. 无法导入cv2模块(Python 3.6)
  10. 报表导出之easypoi的应用