- Java锁的逻辑(结合对象头和ObjectMonitor)
- 还在用饼状图?来瞧瞧这些炫酷的百分比可视化新图形(附代码实现)⛵
- 自动注册实体类到EntityFrameworkCore上下文,并适配ABP及ABPVNext
- 基于Sklearn机器学习代码实战
锁是计算机协调多个进程或线程并发访问某一资源的机制。在数据库中,除了传统的计算资源(CPU、RAM、i/O)的挣用以外,数据也是一种供许多用户共享的资源。如何保证数据并发访问的一致性,有效性是所有数据库必须解决的一个问题,锁冲突也是影响数据库并发访问性能的一个重要因素,从这个角度来说,锁对数据库而言显得尤其重要,也更加复杂.
。
MySQL中的锁、按照锁的粒度分,分为以下三类 。
。
全局锁就是对整个数据库实例枷锁,加锁后整个实例就处于只读状态,后续的DML的写语句,DDL语句,以及更新操作的事物提交语句都会被阻塞,其典型的使用场景是做全库的逻辑备份,对所有的表进行锁定,从而获取一致性视图,保证数据的完整性.
flush tables with read lock;
unlock tables;
说明1:客户端1中设置了全局锁 。
说明2:客户端2中,执行查询语句正常的,但是执行DML语句中的更新操作却是处于阻塞状态 。
说明1:客户端1中设置了全局锁 。
说明2:客户端3中做了数据库备份的语句,其中mysqldump是和mysql一样由MySQL服务器提供的数据库备份的命令 。
说明3:当数据库设置了全局锁的时候,不影响数据库的备份 。
说明4:MySQL备份实在终端命令行模式下,不是在数据库命令模式下,注意!注意!注意! 。
说明1:客户端1释放全局锁 。
说明2:客户端2的更新语句马上执行成功 。
说明3:通过客户端2的更新语句的执行时间37min,可以说明该语句被客户端1的全局锁,阻塞了37分钟 。
数据库中加全局锁,是一个比较重的操作,存在以下问题 。
在innoDB引擎中,我们可以在备份时加上 --single-transaction 参数来完成不加锁的一致性数据备份 。
。
表级锁,每次操作锁住整张表,锁定粒度大,发生锁冲突的概率最高,并发度最低,应用在MyISAM,InnoDB等存储引擎中 。
加锁:lock tables 表名... read/write 。
释放锁:unlock tables / 客户端断开连接 。
说明1:加锁的时候,可以多张表同时加锁 。
说明2:客户端断开连接也能释放表锁 。
。
说明1:当对一个表添加读锁,不会影响其读取数据,但是会影响其新增,修改,删除的操作语句 。
说明2:当对一个表添加读锁,不会影响其他客户端读取数据,但是会让其他客户端的新增,修改,删除等操作语句处于阻塞状态.
说明3:当把锁释放了,自己及其他客户端的新增,删除和修改语句才会结束阻塞.
说明1:添加写锁的客户端可以正常对表进行查询和增删改等操作 。
说明2:其他客户端的查询,修改,新增,删除都操作在有写锁的情况下,都要处于阻塞状态,直到其添加写锁的客户端释放写锁.
说明3:上图中的修改等应该是DML语句(Data Manipulation Language 数据操作语言,用来对数据库表中的数据进行增删改的),不是DDL语句(DDL: Data Definition Language 数据定义语言,用来定义数据库对象,数据库,表,字段) 。
。
元数据锁(meta data lock):简称 MDL 。
MDL加锁过程是系统自动控制,无需显示使用,在访问一张表的时候会自动加上。MDL锁主要作用是维护表元数据的数据一致性,在表上有活动事务的时候,不可以对元数据进行写入操作,为了避免DML和DDL冲突,保证读写的正确性 。
在MySQL5.5 中引入了MDL, 当对一张表进行增删改查的时候,加MDL读锁(共享);当对表结构进行变更操作的时候,加MDL写锁(排他) 。
说明1:select 和 update 分别会添加SHARED_READ 和 SHARED_WRITE, 但是SHARED_READ 和 SHARED_WRITE是兼容的,所以其他客户端是可以做更删改查的 。
说明2:alter table 会产生EXCLUSIVE 锁。该锁与其他MDL都互斥。ß 。
select object_type,object_schema, object_name ,lock_type,locak_duration from performance_schema.metadata_locks;
。
为了避免DML在执行时,加的行锁与表锁的冲突,在InnoDB中引入了意向锁,使得表锁不用检查每一行数据是否加锁,使用意向锁来减少表锁的检查.
情况1:不加意向锁 。
说明1:线程A 开启一个事务,并且使用DML语句更新数据,此时会对更新的数据添加行锁, 。
说明2:此时线程A 的事务并没有提交事务,线程B又对该表添加一个表锁,此时添加表锁的时候,就会从第一条数据,依次检查到最后一条数据,看是否有其他的锁,如果有其他锁,需要等到其他锁释放了,才能执行添加表锁 。
说明3:此时添加表锁的效率就非常低 。
情况2:加意向锁 。
。
说明4:当线程A 开启了一个事务,并且执行了DML的更新数据的语句,此时除了会给该行数据添加行锁之外,还会添加一个基于整表的意向锁.
说明5:当线程B 再次添加表锁的时候,就不用逐行排查是否有行锁了,而是直接检查整表是否有意向锁,如果意向锁和表锁兼容则直接加表锁 。
说明6:如果表锁和意向锁不兼容,则仍然会等到意向锁释放了,表锁才能添加成功.
select object_schema, object_name , index_name, lock_type, lock_mode, lock_data from performance_schema.data_locks;
说明1:客户端1开启事务,并且查询语句时设置一个意向共享锁(IS) 。
说明2:客户端2在客户端1的事务未提交的时候,创建read锁成功 。
说明3:意向共享锁(IS)和read共享锁兼容 。
说明4:执行update等DML语句时,MySQL会自动添加行锁和排他意向锁.
说明5:排他意向锁与共享read锁和排他write锁都互斥 。
说明6:意向锁的作用主要是解决行锁和表锁之间的矛盾.
。
行级锁,每次操作锁住对应的行数据,所得粒度最小,发生锁冲突的概率最低,并发度最高,应用在InnoDB存储引擎中 。
InnoDB的数据是基于 索引组织的 , 行锁是通过对索引上的索引项加锁来实现 的,而不是对记录加的锁,对于行级锁,主要分为一下三类 。
1、行锁(record lock): 锁定单个行记录的锁,防止其他事务对此行进行update和delete,在read committed和repeatable read隔离级别下都支持.
2、间隙锁(Gap lock): 锁定索引记录间隙(不包含记录),确保索引记录间隙不变,防止其他事务在这个间隙进行insert,产生幻读,在repeatable read隔离级别下支持 。
3、临建锁(Next-Key lock): 行锁和间隙锁组合,同时锁住数据,并锁住数据前面的间隙,在repeatable read隔离级别下支持 。
InnoDB 实现了一下两种类型的行锁 。
1、共享锁(S): 允许一个事物去读一行,阻止其他事务获得相同数据集的排他锁.
2、排他锁(X): 允许获取排他锁的事务更新数据,阻止其他事物获得相同数据集的共享锁和排他锁 。
3、不同语句的枷锁情况 。
4、默认情况下,InnoDB在 repeatable read隔离级别下运行,InnoDB使用next-key锁进行行搜索和索引扫描,以防止幻读 。
说明1:客户端1开始事务,并执行查询语句,客户端2锁的情况,显示为空表 。
说明2:客户端执行查询语句,并手动添加共享,在客户端2中,查询lock_mode字段中有一个S,即共享锁: 。
说明3:客户端2也手动开启了一个共享锁,并且成功,说明共享锁与共享锁之间是兼容的.
说明5:在客户端2上执行更新id=2的数据成功,并且查询可以看出,自动增加了一个(X)排它锁.
说明6: 因为更新id=2的数据时,id=2的这一行上没有其他的锁,所以可以执行成功 。
说明7:因为在客户点1上已经对id=1的行上添加了一个共享锁(S), 这是客户端2对id=1的数据做update操作时会自动在id=1的数据上在添加一个排它锁(X),这是id=1的数据上就会有共享锁(S)和排它锁(X),又因为共享锁和排它锁不兼容,所以在update id = 1 的时候就会阻塞,需要等到共享锁(S)释放了,才能执行成功.
说明8:排它锁X 与 排它锁X 也是不兼容的.
说明9:InnoDB的行锁是针对于索引加的锁,不通过索引检索数据,那么InnoDB将对表中的所有记录加锁,此时就会升级为表锁 。
说明10:根据业务需要,尽量使用索引当所查询条件,既快又减少阻塞.
。
9.1 默认情况下、InnoDB在 repeatable read 事务隔离级别运行,InnoDB使用next-key 锁进行搜索和索引扫描,以防止幻读.
9.2 索引上的等值查询(唯一索引),给不存在的记录加锁时,优化为间隙锁 。
9.3 索引上的等值查询(普通索引),向右遍历时最后一个值不满足查询需求时,next-key lock 退化为间隙锁 。
说明1:非唯一索引,即普通索引,在做等值查询的时候,会添加三把锁 。
说明2:在查询的当条记录上添加一个共享锁,允许其他事务继续查询该记录 。
说明3:通过标注6的位置,lock_type 为S,REC_NOT_GAP 说明同时给这一行添加一个行锁 。
说明4:通过标注7的位置,lock_type 为 S,GAP 说明在第一个不满足查询数据的前面也会加一个间隙锁。其目的是为了防止在select 查询的时候,其他事务去往这个索引之前插入或者修改数据,这样查询就会出现幻读的现象.
9.4 索引上的范围查询(唯一索引),会访问到不满足条件的第一个值为止.
注意:间隙锁唯一的目的是防止其他事务插入间隙,间隙锁可以共存,一个事务采用的间隙锁不会阻止另一个事物在同一间隙上采用间隙锁 。
最后此篇关于MySQL高级9-锁的文章就讲到这里了,如果你想了解更多关于MySQL高级9-锁的内容请搜索CFSDN的文章或继续浏览相关文章,希望大家以后支持我的博客! 。
一、公平锁和非公平锁 1.1、公平锁和非公平锁的概述 公平锁:指多个线程按照申请锁的顺序来获取锁。 非公平锁:指在多线程获取锁的顺序并不是按照申请锁的顺序,有可能后申请的线程比先申请的线程优先获取到锁
阅读目录 1、简介 2、分类 3、全局锁 4、表级锁 5、表锁 6、元数据锁
因此,在我编写的程序中,我有三个函数,为了简单起见,我们将它们称为 A、B 和 C。每个函数都需要访问资源X才能工作。 限制是A和B不允许同时运行并且必须适当同步。但是,C 可以与 A 或 B 同时运
我听说过这些与并发编程相关的词,但是锁、互斥量和信号量之间有什么区别? 最佳答案 锁只允许一个线程进入被锁定的部分,并且该锁不与任何其他进程共享。 互斥锁与锁相同,但它可以是系统范围的(由多个进程共享
这个问题已经有答案了: What is an efficient way to implement a singleton pattern in Java? [closed] (29 个回答) 已关闭
这个问题已经有答案了: What is an efficient way to implement a singleton pattern in Java? [closed] (29 个回答) 已关闭
我对标题中的主题有几个问题。首先,假设我们使用 JDBC,并且有 2 个事务 T1 和 T2。在 T1 中,我们在一个特定的行上执行 select 语句。然后我们对该行执行更新。在事务 T2 中,我们
我希望我的函数只运行一次。这意味着如果多个线程同时调用它,该函数将阻塞所有线程,只允许它运行。 最佳答案 听起来您希望存储过程进行同步。为什么不直接将同步放在应用程序本身中。 pthread_mute
if (runInDemoMode) { lock (this) { //Initalization of tables dCreator.create
我相信无论使用什么语言都可以考虑我的问题,但是为了有一些“ anchor ”,我将使用 Java 语言来描述它。 让我们考虑以下场景:我有一个扩展 Thread 的类 PickyHost 及其实例 p
我知道异步不是并行的,但我现在遇到了一个非常有趣的情况。 async function magic(){ /* some processing here */ await async () =
我们正在使用 Scala、Play 框架和 MongoDB(以 ReactiveMongo 作为我们的驱动程序)构建一个网络应用程序。应用程序架构是端到端的非阻塞。 在我们代码的某些部分,我们需要访问
我需要一个简单的锁,JavaME 超时(concurrent.lock 的反向移植需要完整的 Java 1.3)。 如果其他人已经为 JavaME 发布了经过测试的锁定代码,我宁愿使用它。 锁定是出了
根据 boost : To access the object, a weak_ptr can be converted to a shared_ptr using the shared_ptr co
关于 Mutex 和 Critical 部分之间的区别存在一个问题,但它也不处理 Locks。 所以我想知道临界区是否可以用于进程之间的线程同步。 还有信号状态和非信号状态的含义 最佳答案 在 Win
锁 最为常见的应用就是 高并发的情况下,库存的控制。本次只做简单的单机锁介绍。 直接看代码: 每请求一次库存-1. 假如库存1000,在1000个人请求之后,库存将变为0。
线程和进程 1、线程共享创建它的进程的地址空间,进程有自己的地址空间 2、线程可以访问进程所有的数据,线程可以相互访问 3、线程之间的数据是独立的 4、子进程复制线程的数据 5、子进程启动
**摘要:**细心的你也一定关注到,有的网址是https开头的,有的是http。https开头的网站前面,会有一把小锁。这是为什么呢? 本文分享自华为云社区《还不知道SSL证书已经是刚需了?赶快来了解
试图在 C 中实现一个非常简单的互斥锁(锁)我有点困惑。我知道互斥锁类似于二进制信号量,除了互斥锁还强制执行释放锁的线程的约束,必须是最近获得它的同一线程。我对如何跟踪所有权感到困惑? 这是我到目前为
在阅读了很多与上述主题相关的文章和答案之后,我仍然想知道 SQL Server 数据库引擎在以下示例中是如何工作的: 假设我们有一个名为 t3 的表: create table t3 (a int ,
我是一名优秀的程序员,十分优秀!