前言

不管是在面试中,还是在平时的工作中,高并发永远是衡量一个web工作者能力的重要场景。本篇幅我们主要是来讨论在高并发环境下我们应该如何实现分布式锁。

实现分布式锁的方式有比较多,这里主要考虑如何使用mysql实现分布式锁。

Mysql实现锁的方法

第一种,使用mysql唯一索引来实现:

针对这种实现,我们只需要新建一张表,专门用来处理分布式任务,比如新建一张 task的表,里面的唯一索引为 task_name 。

运行流程如下:当多个副本同时要抢占一个任务的锁的时候,就执行一个插入语句(这几个副本的task_name都是一致的),所以,当有一个副本之行插入成功后,后续的其他插入则会由于唯一索引的问题,导致插入失败。我们可以根据插入的影响条数为0 或者是1 ,判断是否抢锁成功。最后抢锁成功的副本,在任务执行结束之后,将该条记录删除,即把锁删除掉。

CREATE TABLE `tests`.`task` (

`task-name` varchar(255) NULL,

`id` int(0) NOT NULL AUTO_INCREMENT,

`ctime` timestamp(0) NULL,

`mtime` timestamp(0) NULL ON UPDATE CURRENT_TIMESTAMP(0),

PRIMARY KEY (`id`),

INDEX `uniq_idx_task_name`(`task-name`)

);

// 副本1执行:

INSERT INTO `tests`.`task`(`task-name`, `ctime`, `mtime`) VALUES ('demo1', 1, NULL, NULL);

// 副本2同时执行

INSERT INTO `tests`.`task`(`task-name`, `ctime`, `mtime`) VALUES ('demo1', 1, NULL, NULL);

// 以上只会有一个副本执行成功,另一个副本会直接失败

第二种,使用mysql的悲观锁

for update 和 for udpate no wait :

使用的前提:基于Innodb,并且在支持事务的情况下可以使用

当某用户执行了 for update 之后,该用户可以在提交或者放弃事务之前,对该事务进行查询和更新,其他用户只能查询但不能更新被加锁的数据行。

** select XXXX for update 在执行过程中可能会锁行,也可能会锁表 。 **

当查询中带有主键的时候,会锁行;

当明确带有(即是使用的不包括模糊查询之类的)主键,但是查询没有结果的,不会导致锁表;

当查询中无主键或者使用了like之类需要全表扫描的,会导致锁住整个表;(即使查询中没有任何数据的时候也会导致锁表)

另外,select XX for update nowait 与 只有 for update 的区别是for update ,当另一个连接尝试获取到锁的时候,会阻塞在那里等待;如果加了 nowait 的话,当获取不到锁的时候会直接报错。

// 为了方便这里借用上上面的task表

// 起一个终端,连接上数据库,然后执行以下:

set autocommit = 0;

select * from task for update;

// 等待一段时间后再执行;

commit;

此时,另一个终端执行,可以发现,执行 select的话,可以直接返回,但是update的话会产生阻塞,直到之前的事务commit(看执行时间就可以知道)

image.png

// 如果使用for update nowait;

// 副本1执行成功:

select * from task for update nowait;

// 副本2执行:

mysql> select * from task for update nowait;

ERROR 3572 (HY000): Statement aborted because lock(s) could not be acquired immediately and NOWAIT is set

//值得注意的是,for update nowait 的话,如果你执行 update 操作的话,仍然会阻塞在那里。

第三种,使用乐观锁

(区分下第一种,第一种是针对单点定时任务的,这里延伸下成加锁)

使用乐观锁的话,可以给表中加一个 version 字段,用于表示该行记录的版本(如果你想要用 timestamp来做也可以,可以直接使用mysql的字段,那样你就不用考虑该值的更新)

因此,每次更新的流程是,先 select 获取到一个version(比如是3) 然后再进行 update ,查询中在原来的基础上多加一个 and version = 3, 如果在select 和 update 之间有个第三方操作了数据库并且操作成功了,此刻version变成了4,那么你进行这次update的时候 update XXX where XXX and version = 3的时候,更新就会失败,那么就不会影响。

结语

以上就是mysql锁的三种方式,不过说实话,mysql的性能确实在高并发环境下,不值得期待,但是多了解下这种知识,也算是扩宽下自己的解决问题的思路吧。

共勉

mysql分布式安装可靠读写案列图解,高并发下的分布式锁-mysql篇相关推荐

  1. MySQL Proxy 安装与读写分离体验

    一直想等到BETA版出来再试验的,可还是经不住诱惑阿,下午终于有时间测试一下了. (本文参考地址:http://blog.chinaunix.net/u/8111/showart.php?id=451 ...

  2. 取代ZooKeeper!高并发下的分布式一致性开源组件StateSynchronizer

    StateSynchronizer是开源分布式流存储平台Pravega的核心组件.StateSynchronizer组件以stream为基础,对外提供一致性状态共享服务.StateSynchroniz ...

  3. 高并发下的分布式缓存浅析

    说到分布式缓存,我们不得不说到两个数据库--memcache.redis,曾经我们使用缓存一般使用memcache,现在我们一般使用redis.那为啥我们从memcache迁移到redis呢?因为re ...

  4. 分布式技术与实战第七课 高并发下高可用的熔断、降级、限流和负载均衡、监控以及统一的日志系统

    第39讲:从双十一看高可用的保障方式 从这一课时开始,专栏内容进入最后一个模块,即分布式高可用系列,这部分的内容,我将以电商大促为背景,讲解系统限流.降级熔断.负载均衡.稳定性指标.系统监控和日志系统 ...

  5. centos mysql无法启动 sock_【零基础学云计算】MYSQL的主从复制、读写分离

    MySQL主从复制的类型 基于语句的复制(默认) 在主服务器上执行的语句,从服务器执行同样的语句 基于行的复制 把改变的内容复制到从服务器 混合类型的复制 一旦发现基于语句无法精确复制时,就会采用基于 ...

  6. MySQL的安装和初次使用

    MySQL的安装和初次使用 1.去数据库的官网http://www.mysql.com下载MySQL: 2.找到如下图所示: 下好后按照next/execut安装即可,会有设置密码页: 安装好以后可能 ...

  7. brew安装mysql 卸载_Ubuntu环境下MySQL卸载安装配置远程访问三步曲

    卸载 查看所有依赖 dpkg --list|grep mysql 卸载 MySQL sudo apt-get remove mysql-* 清除残留数据,弹出界面选择 yes dpkg -l |gre ...

  8. CentOS 6.0 系统 LAMP(Apache+MySQL+PHP)安装步骤

    转自:http://down.chinaz.com/server/201109/1064_1.htm 先来解释一下,什么是 LAMP.正如标题所言,LAMP 实际上就是 Linux.Apache.My ...

  9. 安装解压版本的MySQL,安装过程中的常见命令,检查windows系统错误日志的方式来检查MySQL启动错误,关于Fatal error: Can't open and lock privilege

    安装mysql 下载mysql-5.6.26-winx64,并解压到:D:\Installed\mysql-5.6.26-winx64\mysql-5.6.26-winx64 创建data目录 创建m ...

最新文章

  1. Hopfiled 神经网络实例解释
  2. 敏感性与特异性理解笔记
  3. Netflix CEO哈斯廷斯:内容为王 公司潜力依然巨大
  4. java 异常 规范_java 异常规范
  5. java基础——枚举
  6. Spring Boot分布式系统实践【扩展1】shiro+redis实现session共享、simplesession反序列化失败的问题定位及反思改进...
  7. netty中的引导Bootstrap服务端
  8. android 播放器 直播,通过android中的mediaplayer直播
  9. CUDA 和 GPU
  10. 服务器虚拟化基础hcna,华为云计算全新大纲课程 乾颐堂HCNA-Cloud服务器虚拟化云计算实战课程 HCNA认证课程...
  11. 棋牌游戏开发教程系列:游戏服务器框架搭建
  12. Android+8.0+微信表情,微信8.0表情为什么不动?微信8.0哪些表情有动画效果?
  13. 记录一下线上高并发情况下 SimpleDateFormat 出现异常问题【项目】
  14. 照片模糊怎么变清晰?
  15. ant-bable实现表格输入数据
  16. 网络能力认证CCSC-管理1级 技术1级别
  17. 如何做好微信朋友圈推广?
  18. MicroChip C18编译器上手及环境设置
  19. OpenVR API简单介绍
  20. Coursera-Python for everybody

热门文章

  1. python opencv 内存泄露_解决python中显示图片的plt.imshow plt.show()内存泄漏问题
  2. 产线数字化软件源码_数字化工厂规划的十大核心要素
  3. python的shutil模块是内置的_Python之shutil模块11个常用函数详解,python内置函数是什么...
  4. mysql 时序 存储引擎_MySQL常见的三种存储引擎
  5. 外部接口需求怎么写_软件需求规约怎么写
  6. from .filename import class
  7. python关系运算符可以连续使用_python学习笔记-字符串拼接关系运算符逻辑运算符...
  8. android profile分析器,Android性能优化之分析工具Profile的使用
  9. libsvm java下载_java-libsvm 版 结合已有数据集的demo,方便初学者使用 Develop 238万源代码下载- www.pudn.com...
  10. 路由器 radius认证获取ip_玩转网络工程师·认证篇