锁&事务
一、概述:
锁:是计算机协调多个进程或线程并发访问某一资源的机制,数据库中最重要的资源。数据库既要保证并发性,又要保证数据的一致性,所以锁机制也更复杂。在计算机科学中,锁(lock)或互斥(mutex)是一种同步机制,用于在有许多执行线程的环境中强制对资源的访问限制。锁旨在强制实施互斥排他、并发控制策略。
事务四特性:原子性、一致性、隔离性、持久性。如果没有事务的隔离级别,那么并发事务操作数据库时可能会产生更新丢失即两个并发事务更新同一条数据时最后更新的会覆盖前面的更新,脏读即在一个事务中读取了别的事务还未提交的更新,不可重复读即在一个事务中前后两次读取到的数据不一致,主要针对update操作,且查询条件是=,幻读即一个事务按照相同的查询条件,前后两次读到数据条数不一样,主要针对insert操作,且查询条件是一个范围。
分布式事务:事务的参与者、支持事务的服务器、资源服务器以及事务管理器分别位于不同的分布式系统的不同节点之上。例如在大型电商系统中,下单接口通常会扣减库存、减去优惠、生成订单 id, 而订单服务与库存、优惠、订单 id 都是不同的服务,下单接口的成功与否,不仅取决于本地的 db 操作,而且依赖第三方系统的结果,这时候分布式事务就保证这些操作要么全部成功,要么全部失败。本质上来说,分布式事务就是为了保证不同数据库的数据一致性。分布式事务2pc,3pc及TCC、可靠消息最终一致性如阿里的rocketmq ,具体可参考https://xiaomi-info.github.io/2020/01/02/distributed-transaction/
幂等操作:在编程中一个幂等操作的特点是其任意多次执行所产生的影响均与一次执行的影响相同。幂等函数,或幂等方法,是指可以使用相同参数重复执行,并能获得相同结果的函数。这些函数不会影响系统状态,也不用担心重复执行会对系统造成改变。例如,支付流程中第三方支付系统告知系统中某个订单支付成功,接收该支付回调接口在网络正常的情况下无论操作多少次都应该返回成功。
二、MySQL锁
1、粒度
- 表级锁:各存储引擎最大粒度的锁。因为粒度大,可以避免死锁的问题,但是资源争用的概率高,是并发粒度降低。
- 行级锁:各存储引擎最小粒度的锁。资源争用的概率低,并发粒度大,如存储引擎:InnoDB(通过锁引条件检索数据)
- 页级锁:介于表级锁和行级锁之间, 如存储引擎:DBD
2、锁定程度
- 共享锁:如果mysql读取某一行时给此条数据加了共享锁,那么其他事务也可以读取此条数据或者给此条数据加共享锁。但是其他事务不能为此条事务加排他锁。简单的可以理解共享锁为读锁,加锁方式:select … from tablename lock in share mode。共享所可能会产生死锁。
- 排他锁:如果mysql事务为某一行数据加了排他锁,那么其他事务不能再为这条数据加排他锁或者共享锁,简单可以理解排他锁为写锁,加锁方式:select … from tablename for update。Mysql会自动的给insert update delete操作加排他锁(隐式加锁)
3、锁定方式
- 显示锁定:手动为某一行或者某几行或者某张表加锁
- 隐式锁定:不需要手动参与,mysql存储引擎会在执行的时候自动为相应的数据进行加锁
4、提交
- 自动提交:autocommit=1, 每条sql语句都是一个事务,如果session设置为自动提交,则事务的开始、提交或者回滚由mysql来保证。每次更新操作之后mysql自动提交事务。一个事务提交之后就不会对其他事务造成干扰.
非自动提交:autocommit=0,或用begin开启事务,或者用start transaction开启事务
5、死锁检测
- 当产生死锁的时候,mysql会判断两个事务的大小,决定哪个事务该回滚,Innodb发现死锁之后,会计算出两个事务各自插入、更新或者删除的数据量来判断两个事务的大小。也就是说哪个事务所改变的记录条数越多,在死锁中就越不会被回滚掉。
三、分布式锁
分布式锁:在分布式系统的多进程中,用分布式锁控制多个进程对资源的访问。使用分布式锁可以避免不同节点重复相同的工作,这些工作会浪费资源。比如用户付了钱之后有可能不同节点会发出多封短信。加分布式锁同样可以避免破坏正确性的发生,如果两个节点在同一条数据上面操作,比如多个节点机器对同一个订单操作不同的流程有可能会导致该笔订单最后状态出现错误,造成损失。
线程锁:主要用来给方法、代码块加锁。当某个方法或代码使用锁,在同一时刻仅有一个线程执行该方法或该代码段。线程锁只在同一JVM中有效果,因为线程锁的实现在根本上是依靠线程之间共享内存实现的,比如Synchronized、Lock等。
进程锁:为了控制同一操作系统中多个进程访问某个共享资源,因为进程具有独立性,各个进程无法访问其他进程的资源,因此无法通过synchronized等线程锁实现进程锁。
乐观锁:乐观锁机制采取了更加宽松的加锁机制,提交更新的时候才检查是否冲突
悲观锁:具有强烈的独占和排他特性。
分布式锁特点:
- 互斥性: 同一时刻只能有一个进程持有锁
- 可重入性: 同一节点上的同一个进程如果获取了锁,能够再次获取锁
- 锁超时:支持锁超时,防止死锁
- 高效和高可用: 加锁和解锁需要高效,同时也需要保证高可用,防止分布式锁失效
- 具备阻塞和非阻塞性:和ReentrantLock一样支持lock和trylock以及tryLock(long timeOut)
- 支持公平锁和非公平锁(可选):公平锁的意思是按照请求加锁的顺序获得锁,非公平锁就相反是无序的。这个一般来说实现的比较少。
常见的分布式锁:
- 基于数据库的分布式锁:
- 基于数据库乐观锁的分布式锁采用的是多版本并发控制机制,资源竞争不是很强的情况下,可以使用数据库乐观锁版本号。
- 基于数据库表的分布式锁-基于唯一键:创建一张表,当我们要锁住某个资源的时候,就往表里面增加一条数据,并对资源名字段做唯一性约束。
- 基于数据库悲观锁的分布式锁-基于数据库排他锁,优点是不需要维护额外的第三方中间件如redis、ZK,缺点是实现起来比较繁琐,需要自己考虑锁冲入、锁超时、加事务等等,一般对比缓存来说性能较低,对于高并发场景并不是很适合。
- 基于Redis的分布式锁:
- 加锁:SETNX key value,当键不存在时,对键进行设置操作并返回成功,否则返回失败。KEY 是锁的唯一标识,一般按业务来决定命名。
- 解锁:DEL key,通过删除键值对释放锁,以便其他线程可以通过 SETNX 命令来获取锁。
- 锁超时:EXPIRE key timeout, 设置 key 的超时时间,以保证即使锁没有被显式释放,锁也可以在一定时间后自动释放,避免资源被永远锁住。
- 基于Zookeeper的分布式锁(参考:https://www.imooc.com/article/284956?block_id=tuijian_wz)
- Zookeeper(业界简称zk):是一种提供配置管理、分布式协同以及命名的中心化服务,这些提供的功能都是分布式系统中非常底层且必不可少的基本功能,但是如果自己实现这些功能而且要达到高吞吐、低延迟同时还要保持一致性和可用性,实际上非常困难。因此zookeeper提供了这些功能,开发者在zookeeper之上构建自己的各种分布式系统。
- ZK节点特性:(1)有序节点:假如当前有一个父节点为/test_lock,我们可以在这个父节点下面创建子节点;zookeeper提供了一个可选的有序特性;(2)临时节点:客户端可以建立一个临时节点,在会话结束或者会话超时后,zookeeper会自动删除该节点。(3)事件监听:在读取数据时,我们可以同时对节点设置事件监听,当节点数据或结构变化时,zookeeper会通知客户端。当前zookeeper有如下四种事件:1)节点创建;2)节点删除;3)节点数据修改;4)子节点变更。
- 优缺点:优点是ZK 可以不需要关心锁超时时间,实现起来有现成的第三方包,比较方便,并且支持读写锁,ZK 获取锁会按照加锁的顺序,所以其是公平锁。对于高可用利用 ZK 集群进行保证。缺点是ZK 需要额外维护,增加维护成本,性能和 MySQL 相差不大,依然比较差。
锁类型 |
优点 |
缺点 |
适用场景 |
基于数据库 |
理解起来简单,不需要维护额外的第三方中间件(比如 Redis,ZK)。 |
虽然容易理解但是实现起来较为繁琐,需要自己考虑锁超时,加事务等等。性能局限于数据库,一般对比缓存来说性能较低。对于高并发的场景并不是很适合。 |
MySQL 分布式锁一般适用于资源不存在数据库,如果数据库存在比如订单,可以直接对这条数据加行锁,不需要我们上面多的繁琐的步骤。 |
基于Redis |
Redis的话实现比较简单,同时性能很好,引入集群可以提高可用性。同时定期失效的机制可以解决因网络抖动锁删除失败的问题。 |
需要维护 Redis集群,如果要实现 RedLock需要维护更多的集群。 |
性能最好,适合高并发场景 |
基于Zookeeper |
ZK 可以不需要关心锁超时时间,实现起来有现成的第三方包,比较方便,并且支持读写锁,ZK 获取锁会按照加锁的顺序,所以其是公平锁。对于高可用利用 ZK 集群进行保证。 |
ZK 需要额外维护,增加维护成本,性能和 MySQL 相差不大,依然比较差。 |
主要是用来解决分布式应用中经常遇到的一些数据管理问题:数据发布与订阅、分布式应用配置项、统一命名服务等等 |
锁&事务的更多相关文章
- 温故知新-Mysql锁&事务&MVCC
文章目录 锁概述 锁分类 MyISAM 表锁 InnoDB 行锁 事务及其ACID属性 InnoDB 的行锁模式 注意 MVCC InnoDB 中的 MVCC 参考 你的鼓励也是我创作的动力 Post ...
- sql server中的锁 事务锁 更新锁 保持锁 共享锁 你知道吗?
锁定数据库的一个表 SELECT * FROM table WITH (HOLDLOCK) 注意: 锁定数据库的一个表的区别 SELECT * FROM table WITH (HOLDLOCK) 其 ...
- 理解MySql的锁&事务隔离级别
这几篇文章是从网上(http://www.hollischuang.com)看到的一系列文章,也是重温了一下数据库的相关知识.下面是对这些文章的一些前后行文逻辑的说明: 我们知道,在DBMS的多个事业 ...
- mysql 锁 事务隔离级别
主题 最近在看mysql相关的书籍.实验了一些内容.分享一下,主要是关于事务隔离级别(read-committed和repeatable-read)和锁相关的. 很多网上文章上都能搜索到 read-c ...
- mysql innodb存储引擎 锁 事务
以下内容翻译自mysql5.6官方手册. InnoDB是一种通用存储引擎,可平衡高可靠性和高性能.在MySQL 5.6中,InnoDB是默认的MySQL存储引擎.除非已经配置了不同的默认存储引擎, ...
- (7)MySQL进阶篇SQL优化(InnoDB锁-事务隔离级别 )
1.概述 在我们在学习InnoDB锁知识点之前,我觉得有必要让大家了解它的背景知识,因为这样才能让我们更系统地学习好它.InnoDB与MyISAM的最大不同有两点:一是支持事务(TRANSACTION ...
- hibernate的乐观锁和悲观锁+事务
hibernate实现数据库操作的乐观锁和悲观锁参看:https://blog.csdn.net/chang_ge/article/details/79695813https://www.cnblog ...
- SQL Server中的事务与锁
了解事务和锁 事务:保持逻辑数据一致性与可恢复性,必不可少的利器. 锁:多用户访问同一数据库资源时,对访问的先后次序权限管理的一种机制,没有他事务或许将会一塌糊涂,不能保证数据的安全正确读写. 死锁: ...
- 【转】SQL Server中的事务与锁
SQL Server中的事务与锁 了解事务和锁 事务:保持逻辑数据一致性与可恢复性,必不可少的利器. 锁:多用户访问同一数据库资源时,对访问的先后次序权限管理的一种机制,没有他事务或许将会一塌糊涂 ...
随机推荐
- Docker的镜像理解以及容器的备份、恢复和迁移操作
Docker的镜像理解以及容器的备份.恢复和迁移操作 这篇文章主要介绍了Docker的镜像理解以及容器的备份.恢复和迁移操作,覆盖很多原理知识以及容器的重要操作步骤,极力推荐!需要的朋友可以参考下 D ...
- python split方法
split方法说明: split方法通过指定分隔符对字符串进行切片,如果参数num有指定值,则分隔num+1个子字符串 split()方法语法: 1 str.split(str="&qu ...
- SpringCloud(八)Sleuth 分布式请求链路跟踪
SpringCloud Sleuth 分布式请求链路跟踪 概述 为什么会出现这个技术?需要解决哪些问题? 在微服务框架中,一个由客户端发起的请求在后端系统中会经过多个不同的的服务节点调用来协同产生最后 ...
- CVPR2020:基于层次折叠的跳跃式注意网络点云完成
CVPR2020:基于层次折叠的跳跃式注意网络点云完成 Point Cloud Completion by Skip-Attention Network With Hierarchical Foldi ...
- 使用adb命令在模拟器安装apk
1.adb connect 127.0.0.1:7555 连接网易模拟器地址2.adb devices -L 查看有几个连接端口地址3.执行推送配置文件 命令 adb push 文件 路径
- Java期末考试编程题复习
在程序中定义Person类,为该类编写如下字段.构造器.访问器.修改器和相应的其他方法.(20分) <1>在Person类中定义两个字段: 私有访问权限,类型为String的name字段: ...
- [源码解析] 深度学习分布式训练框架 horovod (5) --- 融合框架
[源码解析] 深度学习分布式训练框架 horovod (5) --- 融合框架 目录 [源码解析] 深度学习分布式训练框架 horovod (5) --- 融合框架 0x00 摘要 0x01 架构图 ...
- 【模板】O(nlongn)求LIS
合理运用单调性降低复杂度 平常用的都是O(n^2)的dp求LIS(最长不下降子序列)这里介绍O(nlogn)的算法 分析 对于可能出现的x<y<i且A[y]<A[x]<A[i] ...
- NOIP模拟测试9「随·单·题」
liu_runda出的题,先$\%\%\%\%\%\%\%\%\%\%\%$为敬 随 考试时没有Qj 然后甚至没做,甚至没交 我不知道我怎么想的 这个题挺难改 你需要用到 循环矩阵快速幂,矩阵快速幂优 ...
- Pytest学习笔记3-fixture
前言 个人认为,fixture是pytest最精髓的地方,也是学习pytest必会的知识点. fixture用途 用于执行测试前后的初始化操作,比如打开浏览器.准备测试数据.清除之前的测试数据等等 用 ...