一、概述:

锁:是计算机协调多个进程或线程并发访问某一资源的机制,数据库中最重要的资源。数据库既要保证并发性,又要保证数据的一致性,所以锁机制也更复杂。在计算机科学中,锁(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)
  • 支持公平锁和非公平锁(可选):公平锁的意思是按照请求加锁的顺序获得锁,非公平锁就相反是无序的。这个一般来说实现的比较少。

常见的分布式锁:

  • 基于数据库的分布式锁:
  1. 基于数据库乐观锁的分布式锁采用的是多版本并发控制机制,资源竞争不是很强的情况下,可以使用数据库乐观锁版本号。
  2. 基于数据库表的分布式锁-基于唯一键:创建一张表,当我们要锁住某个资源的时候,就往表里面增加一条数据,并对资源名字段做唯一性约束。
  3. 基于数据库悲观锁的分布式锁-基于数据库排他锁,优点是不需要维护额外的第三方中间件如redis、ZK,缺点是实现起来比较繁琐,需要自己考虑锁冲入、锁超时、加事务等等,一般对比缓存来说性能较低,对于高并发场景并不是很适合。
  • 基于Redis的分布式锁:
  1. 加锁:SETNX key value,当键不存在时,对键进行设置操作并返回成功,否则返回失败。KEY 是锁的唯一标识,一般按业务来决定命名。
  2. 解锁:DEL key,通过删除键值对释放锁,以便其他线程可以通过 SETNX 命令来获取锁。
  3. 锁超时:EXPIRE key timeout, 设置 key 的超时时间,以保证即使锁没有被显式释放,锁也可以在一定时间后自动释放,避免资源被永远锁住。

      

  • 基于Zookeeper的分布式锁(参考:https://www.imooc.com/article/284956?block_id=tuijian_wz)
  1. Zookeeper(业界简称zk):是一种提供配置管理、分布式协同以及命名的中心化服务,这些提供的功能都是分布式系统中非常底层且必不可少的基本功能,但是如果自己实现这些功能而且要达到高吞吐、低延迟同时还要保持一致性和可用性,实际上非常困难。因此zookeeper提供了这些功能,开发者在zookeeper之上构建自己的各种分布式系统。
  2. ZK节点特性:(1)有序节点:假如当前有一个父节点为/test_lock,我们可以在这个父节点下面创建子节点;zookeeper提供了一个可选的有序特性;(2)临时节点:客户端可以建立一个临时节点,在会话结束或者会话超时后,zookeeper会自动删除该节点。(3)事件监听:在读取数据时,我们可以同时对节点设置事件监听,当节点数据或结构变化时,zookeeper会通知客户端。当前zookeeper有如下四种事件:1)节点创建;2)节点删除;3)节点数据修改;4)子节点变更。
  3. 优缺点:优点是ZK 可以不需要关心锁超时时间,实现起来有现成的第三方包,比较方便,并且支持读写锁,ZK 获取锁会按照加锁的顺序,所以其是公平锁。对于高可用利用 ZK 集群进行保证。缺点是ZK 需要额外维护,增加维护成本,性能和 MySQL 相差不大,依然比较差。

锁类型

优点

缺点

适用场景

基于数据库

理解起来简单,不需要维护额外的第三方中间件(比如 Redis,ZK)。

虽然容易理解但是实现起来较为繁琐,需要自己考虑锁超时,加事务等等。性能局限于数据库,一般对比缓存来说性能较低。对于高并发的场景并不是很适合。

MySQL 分布式锁一般适用于资源不存在数据库,如果数据库存在比如订单,可以直接对这条数据加行锁,不需要我们上面多的繁琐的步骤。

基于Redis

Redis的话实现比较简单,同时性能很好,引入集群可以提高可用性。同时定期失效的机制可以解决因网络抖动锁删除失败的问题。

需要维护 Redis集群,如果要实现 RedLock需要维护更多的集群。

性能最好,适合高并发场景

基于Zookeeper

ZK 可以不需要关心锁超时时间,实现起来有现成的第三方包,比较方便,并且支持读写锁,ZK 获取锁会按照加锁的顺序,所以其是公平锁。对于高可用利用 ZK 集群进行保证。

ZK 需要额外维护,增加维护成本,性能和 MySQL 相差不大,依然比较差。

主要是用来解决分布式应用中经常遇到的一些数据管理问题:数据发布与订阅、分布式应用配置项、统一命名服务等等

锁&事务的更多相关文章

  1. 温故知新-Mysql锁&事务&MVCC

    文章目录 锁概述 锁分类 MyISAM 表锁 InnoDB 行锁 事务及其ACID属性 InnoDB 的行锁模式 注意 MVCC InnoDB 中的 MVCC 参考 你的鼓励也是我创作的动力 Post ...

  2. sql server中的锁 事务锁 更新锁 保持锁 共享锁 你知道吗?

    锁定数据库的一个表 SELECT * FROM table WITH (HOLDLOCK) 注意: 锁定数据库的一个表的区别 SELECT * FROM table WITH (HOLDLOCK) 其 ...

  3. 理解MySql的锁&事务隔离级别

    这几篇文章是从网上(http://www.hollischuang.com)看到的一系列文章,也是重温了一下数据库的相关知识.下面是对这些文章的一些前后行文逻辑的说明: 我们知道,在DBMS的多个事业 ...

  4. mysql 锁 事务隔离级别

    主题 最近在看mysql相关的书籍.实验了一些内容.分享一下,主要是关于事务隔离级别(read-committed和repeatable-read)和锁相关的. 很多网上文章上都能搜索到 read-c ...

  5. mysql innodb存储引擎 锁 事务

    以下内容翻译自mysql5.6官方手册. InnoDB是一种通用存储引擎,可平衡高可靠性和高性能.在MySQL 5.6中,InnoDB是默认的MySQL存储引擎.除非已经配置了不同的默认存​​储引擎, ...

  6. (7)MySQL进阶篇SQL优化(InnoDB锁-事务隔离级别 )

    1.概述 在我们在学习InnoDB锁知识点之前,我觉得有必要让大家了解它的背景知识,因为这样才能让我们更系统地学习好它.InnoDB与MyISAM的最大不同有两点:一是支持事务(TRANSACTION ...

  7. hibernate的乐观锁和悲观锁+事务

    hibernate实现数据库操作的乐观锁和悲观锁参看:https://blog.csdn.net/chang_ge/article/details/79695813https://www.cnblog ...

  8. SQL Server中的事务与锁

    了解事务和锁 事务:保持逻辑数据一致性与可恢复性,必不可少的利器. 锁:多用户访问同一数据库资源时,对访问的先后次序权限管理的一种机制,没有他事务或许将会一塌糊涂,不能保证数据的安全正确读写. 死锁: ...

  9. 【转】SQL Server中的事务与锁

    SQL Server中的事务与锁   了解事务和锁 事务:保持逻辑数据一致性与可恢复性,必不可少的利器. 锁:多用户访问同一数据库资源时,对访问的先后次序权限管理的一种机制,没有他事务或许将会一塌糊涂 ...

随机推荐

  1. 大师画PCB板子

    1.低频电路对于模拟地和数字地要分开布线,不能混用 2.如果有多个A/D转换电路,几个ADC尽量放在一起,只在尽量靠近该器件处单点接地,AGND和DGND都要接到模拟地,电源端子都要接到模拟电源端子: ...

  2. 【数据结构与算法】多种语言(VB、C、C#、JavaScript)系列数据结构算法经典案例教程合集目录

    目录 1. 专栏简介 2. 专栏地址 3. 专栏目录 1. 专栏简介 2. 专栏地址 「 刘一哥与GIS的故事 」之<数据结构与算法> 3. 专栏目录 [经典回放]多种语言系列数据结构算法 ...

  3. .Net Core with 微服务 - Ocelot 网关

    上一次我们通过一张架构图(.Net Core with 微服务 - 架构图)来讲述了微服务的结构,分层等内容.从现在开始我们开始慢慢搭建一个最简单的微服务架构.这次我们先用几个简单的 web api ...

  4. 设计模式Copy-on-write

    1.Copy-on-Write 又称COW,写时复制 String的replace()方法,没有修改内部的value数组,而是新创建了一个不可变对象 这种方法在解决不可变对象时,经常使用 这其实就是一 ...

  5. TVM 优化 ARM GPU 上的移动深度学习

    TVM 优化 ARM GPU 上的移动深度学习 随着深度学习的巨大成功,将深度神经网络部署到移动设备的需求正在迅速增长.与桌面平台上所做的类似,在移动设备中使用 GPU 既有利于推理速度,也有利于能源 ...

  6. 如果攻击者操控了 redirect_uri,会怎样?

    读者在看这篇文章之前,请先了解 Oauth2.0 的 Authorization Code 授权流程,可以看 Authorization Code 授权原理和实现方法 在 Token Enpoint ...

  7. 简单测试 APISIX2.6 网关

    Apache APISIX是一个动态的.实时的.高性能的 API 网关.它提供丰富的流量管理功能,例如负载均衡.动态上游服务.金丝雀发布.断路.身份验证.可观察性等.您可以使用 Apache APIS ...

  8. 【NX二次开发】Block UI 从列表选择部件

    属性说明 属性   类型   描述   常规           BlockID    String    控件ID    Enable    Logical    是否可操作    Group    ...

  9. 【SQLite】教程01-SQLite简介与安装

    为什么要用 SQLite? 不需要一个单独的服务器进程或操作的系统(无服务器的). SQLite 不需要配置,这意味着不需要安装或管理. 一个完整的 SQLite 数据库是存储在一个单一的跨平台的磁盘 ...

  10. 「题解」黑暗塔 wizard

    本文将同步发布于: 洛谷博客: csdn: 博客园: 简书. 题目 题意简述 给定 \(y\),求 \(\varphi(x)=y\) 中 \(x\) 的个数和最大值. \(1\leq y\leq 10 ...