精华内容
下载资源
问答
  • 深入理解数据库行锁表锁 在上一章节中我们学习了数据库的事务及其事务的隔离级别,但是数据库是怎样隔离事务的呢?这时候就牵连到了数据库锁。当插入数据时,就锁定表,这叫做”锁表”;当更新数据时,就锁定行,...

    深入理解数据库行锁与表锁

    在上一章节中我们学习了数据库的事务及其事务的隔离级别,但是数据库是怎样隔离事务的呢?这时候就牵连到了数据库锁。当插入数据时,就锁定表,这叫做”锁表”;当更新数据时,就锁定行,这叫做”锁行”。

    锁在数据网络传输中是一个非常重要的概念,当多个用户对数据库进行操作时,会带来数据不一致的情况,所以,锁主要是在多用户情况下保证数据库数据完整性和一致性。

    当然,数据库中的锁远不止于上面提到的两种。通常提及数据库锁,想必大家优先想到的,必然是乐观锁,数据库乐观锁可以帮助我们解决很多问题,但数据库中还有很多其它的锁,总结一下大概有如下:悲观锁、乐观锁、表锁、行锁、临间锁、间隙锁、记录锁、共享锁、排他锁、意向共享锁、意向排他锁。

    上面一共提到了11种锁,如果给它们进行分类,大抵可以按如下划分:

    img

    img

    乐观锁和悲观锁这个不用再多说了,相信大家也都是知道的。Mysql中的锁机制基本上都是采用的悲观锁来实现的。我们先来看一下”行锁”。

    行锁

    顾名思义,行锁就是一锁锁一行或者多行记录,mysql的行锁是基于索引加载的,所以行锁是要加在索引响应的行上,即命中索引,如下图所示:

    img

    如上图所示,数据库表中有一个主键索引和一个普通索引,Sql语句基于索引查询,命中两条记录。此时行锁一锁就锁定两条记录,当其他事务访问数据库同一张表时,被锁定的记录不能被访问,其他的记录都可以访问到。

    行锁的特征:锁冲突概率低,并发性高,但是会有死锁的情况出现。

    我们使用代码演示一下,看看行锁的表现:我们还是使用上一篇文章中使用的数据库,打开两个窗口,我们在窗口A中根据id更新一条记录,然后在窗口B中也执行相同的SQL语句看看

    img

    可以看到,窗口A先修改了id为3的用户信息后,还没有提交事务,此时窗口B再更新同一条记录,然后就提示Lock wait timeout exceeded; try restarting transaction ,由于窗口A迟迟没有提交事务,导致锁一直没有释放,就出现了锁冲突,而窗口B一直在等待锁,所以出现了超过锁定超时的警告了。

    但是,此时我们如果去更新id为3它旁边的记录看看会出现怎样的情况,我们新打开一个窗口更新id为2的记录看看。

    img

    可以看到,在窗口B中更新id为3的记录报错,但是在窗口C中我们可以更新id为2的记录,这说明此时锁定了id为3的记录但是并没有锁定它旁边的记录。

    表锁

    顾名思义,表锁就是一锁锁一整张表,在表被锁定期间,其他事务不能对该表进行操作,必须等当前表的锁被释放后才能进行操作。表锁响应的是非索引字段,即全表扫描,全表扫描时锁定整张表,sql语句可以通过执行计划看出扫描了多少条记录。

    img

    由于表锁每次都是锁一整张表,所以表锁的锁冲突几率特别高,表锁不会出现死锁的情况。

    和上面一样,我们通过代码演示一下,看看表锁的表现,我们打开两个窗口,在窗口A中更新一条记录,条件为非索引字段,不提交事务,然后在窗口B中任意再更新一条记录,我们看看会出现怎样的现象:

    img

    上面,我们分别验证了一下mysq的行锁和表锁,我们可以看到,当更新数据库数据时,如果没有触发索引,则会锁表,锁表后再对表做任何变更操作都会导致锁冲突,所以表锁的锁冲突概率较高。

    在mysql中,行锁又衍生了其他几种算法锁,分别是 记录锁、间隙锁、临键锁;我们依次来看看这三种锁,什么是记录锁呢?

    记录锁

    上面我们找到行锁是命中索引,一锁锁的是一张表的一条记录或者是多条记录,记录锁是在行锁上衍生的锁,我们来看看你记录锁的特征:

    记录锁:记录锁锁的是表中的某一条记录,记录锁的出现条件必须是精准命中索引并且索引是唯一索引,如主键id,就像我们上面描述行锁时使用的sql语句图,在这里就挺适用的。

    img

    图中id是唯一索引,此时锁的就是一条记录,命中索引为唯一索引,此时使用的锁就是记录锁了。相信学习完行锁后,再学习记录锁就简单很多了吧。

    间隙锁

    间隙锁又称之为区间锁,每次锁定都是锁定一个区间,隶属行锁。既然间隙锁隶属行锁,那么,间隙锁的触发条件必然是命中索引的,当我们查询数据用范围查询而不是相等条件查询时,查询条件命中索引,并且没有查询到符合条件的记录,此时就会将查询条件中的范围数据进行锁定(即使是范围库中不存在的数据也会被锁定),我们通过代码演示一下:

    首先,我们打开两个窗口,在窗口A中我们根据id做一个范围更改操作,不提交事务,然后在范围B中插入一条记录,该记录的id值位于窗口A中的条件范围内,我们看看运行效果:

    img

    如上所示,程序报错:Lock wait timeout exceeded; try restarting transaction 。这就是间隙锁的作用。间隙锁只会出现在可重复读的事务隔离级别中,mysql5.7默认就是可重复读。间隙锁锁的是一个区间范围,查询命中索引但是没有匹配到相关记录时,锁定的是查询的这个区间范围,上述代码中,所锁定的区间就是 (1,3]这个区间,不包含1,但是包含3,并且不包含4,也就是说这里是一个左开右闭的区间。

    如果我们将mysql数据库隔离级别修改为不可重复读,然后再运行一下上面代码,看看会是怎样的呢,我们来验证一下间隙锁只会出现在可重复读的事务隔离级别中:

    设置事务隔离级别为不可重复读
    set session transaction isolation level read committed;
    查看当前事务级别
    SELECT @@tx_isolation
    

    我们修改数据库隔离级别后,然后将上面的代码流程再走一遍看看:

    img

    可以看到,修改了数据库隔离级别后,再次测试间隙锁,发现间隙锁没有生效。我们可以通过rollback回滚事务。

    临键锁

    学习完间隙锁后我们再来看看什么是临键锁,mysql的行锁默认就是使用的临键锁,临键锁是由记录锁和间隙锁共同实现的,上面我们学习间隙锁时,间隙锁的触发条件是命中索引,范围查询没有匹配到相关记录。而临键锁恰好相反,临键锁的触发条件也是查询条件命中索引,不过,临键锁有匹配到数据库记录

    上面我们知道,间隙锁所锁定的区间是一个左开右闭的集合,而临键锁锁定是当前记录的区间和下一个记录的区间,我们一起来看看:

    img

    img

    从上图我们可以看到,数据库中只有三条数据1、5、7,当修改范围为1~8时,则锁定的区间为(1,+∞),锁定额不单是查询范围,并且还锁定了当前范围的下一个范围区间,此时,查询的区间8,在数据库中是一个不存在的记录值,并且,如果此时的查询条件是小于或等于8,也是一样的锁定8到后面的区间。

    如果查询的结尾是一个存在的值,此时又会怎样呢?现在数据库有三条数据id分别是1、5、7,我们查询条件改为大于1小于7再看看。

    img

    此时,我们可以看到,由于7在数据库中是已知的记录,所以此时的锁定后,只锁定了(1,7],7之后的数据都没有被锁定。我们还是可以正常插入id为8的数据及其后面的数据。

    所以,临键锁锁定区间和查询范围后匹配值很重要,如果后匹配值存在,则只锁定查询区间,否则锁定查询区间和后匹配值与它的下一个值的区间。

    但是,为什么会出现这种情况呢?为什么临键锁后匹配会这样呢?在这里,我们不妨看看mysql的索引是怎么实现的,前面文章中有提到树结构,mysql的索引是基于B+树实现的,每个树节点上都有多个元素,即关键字数,当我们的索引树上只有1、5、7时,我们查询1~8,这个时候由于树节点关键字中并没有8,所以就把8到正无穷的区间范围都给锁定了。

    但是,为什么会出现这种情况呢?为什么临键锁后匹配会这样呢?在这里,我们不妨看看mysql的索引是怎么实现的,前面文章中有提到树结构,mysql的索引是基于B+树实现的,每个树节点上都有多个元素,即关键字数,当我们的索引树上只有1、5、7时,我们查询1~8,这个时候由于树节点关键字中并没有8,所以就把8到正无穷的区间范围都给锁定了。

    那么,如果我们数据库中id有1、5、7、10,此时我们再模糊匹配id为1~8的时候,由于关键字中并没有8,所以找比8大的,也就找到了10,根据左开右闭原则,此时10也是被锁定的,但是id为11的记录还是可以正常进行插入的。这里我没有测试,感兴趣的朋友可以下去自己尝试一下。我们的锁都是基于索引的,而mysql中索引的底层是使用的B+树,我们了解了B+树的特性后,就更容易理解很多遇到锁的问题了。

    展开全文
  • 数据库锁(行锁表锁,共享锁,排他锁) 行锁 我们知道mysql的Innodb引擎是支持行锁的,与Oracle不同,mysql的行锁是通过索引加载的,即行锁是加载索引响应的行上的,要是对应的SQL语句没有索引,则会走表锁行锁...
  • MySQL MySQL(InnoDB存储引擎)默认是自动提交事务的,所以这个测试,需要先将MySQL的...这里我主要针对的是悲观锁,其实也就是行锁和表锁,SQL 加上 FOR UPDATE 即可 行锁 这个时候,我们再开启一个客户端访问...

    MySQL

    MySQL(InnoDB存储引擎)默认是自动提交事务的,所以这个测试,需要先将MySQL的autocommit设置为0,关闭自动提交,需要自己手动提交事务

    -- 关闭自动提交
    set autocommit=0;
    -- 开启事务
    begin;

    这里我主要针对的是悲观锁,其实也就是行锁和表锁,SQL 加上 FOR UPDATE 即可

    行锁

    这个时候,我们再开启一个客户端访问MySQL,输入同一条加锁的SQL查询

    这个时候是没有任何结果的,因为t_card表已经加锁了(这个时候其实加的是行锁),所以cardid=‘1’ 这一行的其他加锁操作是无效的

    但是不加锁查询这一条记录却是可以的

    也就是说虽然这一条记录所在的行被锁定了,但是并不影响我们正常的查询,当然了针对这一行的DML操作也是无效的

    那如果我们对除了cardid=‘1’ 的其他行操作会怎样呢?

    对于其他的行DML是完全没问题的,所以我在前面才说这是行锁,因为只有我们的cardid=‘1’的行被锁了

    好吧,我们放过cardid=‘1’这一行吧

    提交事务之后,另一边的加锁SQL才会生效

    表锁

    上面我们测试的只是行锁,那表锁,或者说怎样才会发生表锁?

    没错,我们不根据主键查询,而是查询所有的记录,MySQL就对整张表加锁了,这不就是表锁了嘛。对于这张表的任何记录进行DML都是无效的

    同时我们对于这张表的任何行进行加锁SQL操作是无效的,那普通的SQL查询又怎样呢?

    还好,这不妨碍我们的普通查询,毕竟查询是与锁这东西没什么缘分的

    结论

    只要有锁存在的地方(无论是一行还是整张表),我们对有锁的地方进行任何加锁SQL都是无效的,当然了DML也是无效的;但是我们的普通查询是没有问题的,同时对于没有锁的行也是可以进行DML操作的

    至于如何解除锁,可以查看这篇博客: https://zhengdl126.iteye.com/blog/1570865 。最后记得把MySQL的autocommit = 1

    Oracle

    Oracle是需要我们手动提交事务的,所以,我们不需要任何设置即可测试

    只有提交事务之后,另一边才会生效,同样的普通查询是没有问题的。如果不根据主键查询,就会锁整张表。最后的结论是与MySQL一致的

    查看哪张表被锁以及解锁

    -- 查看哪张表被锁
    SELECT object_name, machine, s.sid, s.serial#, logon_time, locked_mode
    FROM gv$locked_object l, dba_objects o, gv$session s 
    WHERE l.object_id = o.object_id 
    AND l.session_id = s.sid;
    
    -- 解锁(根据上边SQL查询结果得到sid和serial#)
    --alter system kill session 'sid,serial#'; 
    ALTER system kill session '23,1647'; 

     

    转载于:https://www.cnblogs.com/lz2017/p/10284865.html

    展开全文
  • 随着应用对事务完整性并发性要求的不断提高,MySQL才开始开发基于事务的存储引擎,后来慢慢出现了支持页锁的BDB存储引擎支持行锁的InnoDB存储引擎(实际 InnoDB是单独的一个公司,现在已经被Oracle公司收购)。...

    1、MyISAM表锁

    MyISAM存储引擎只支持表锁,这也是MySQL开始几个版本中唯一支持的锁类型。随着应用对事务完整性和并发性要求的不断提高,MySQL才开始开发基于事务的存储引擎,后来慢慢出现了支持页锁的BDB存储引擎和支持行锁的InnoDB存储引擎(实际 InnoDB是单独的一个公司,现在已经被Oracle公司收购)。但是MyISAM的表锁依然是使用最为广泛的锁类型。

    1.1、MySql表级的锁模式

    MySql的表级锁有两种模式:表共享读锁(Table Read Lock)表独占写锁(Table Write Lock)

    锁模式的兼容性

    请求锁模式 是否兼容当前锁模式None读锁写锁
    读锁
    写锁
    • 对MyISAM表的读操作,不会阻塞其他用户对同一表的读请求,但会阻塞对同一表的写请求
    • 对 MyISAM表的写操作,则会阻塞其他用户对同一表的读和写操作
    • MyISAM表的读操作与写操作之间,以及写操作之间是串行的!

    1.2、如何加表锁

    MyISAM在执行查询语句(SELECT)前,会自动给涉及的所有表加读锁;

    在执行更新操作(UPDATE、DELETE、INSERT等)前,会自动给涉及的表加写锁;

    这个过程并不需要用户干预,因此,用户一般不需要直接用LOCK TABLE命令给MyISAM表显式加锁。

    • Lock TABLES给表显示加表锁时,必须同时取得所有涉及到的表的锁,并且MYSQL不支持锁升级
    • 在执行Lock TABLES后,只能访问显示加锁的表,不能访问未加锁的表
    • 如果是读锁,只能执行查询操作,而不能执行更新操作
    • 在自动加锁的情况下,MYISAM总是一次性获得SQL语句所需要全部锁
    • 当使用Lock Table时,不仅需要一次锁定用到的表,而且,同一个表在SQL语句中出现多少次,就要通过SQL语句中相同的别名锁定多少次

    1.3、并发插入

    上文提到过MyISAM表的读和写是串行的,但这是就总体而言的。在一定条件下,MyISAM表也支持查询和插入操作的并发进行。

    MyISAM存储引擎有一个系统变量concurrent_insert,专门用以控制其并发插入的行为,其值分别可以为0、1或2。

    • 当concurrent_insert设置为0时,不允许并发插入。
    • 当concurrent_insert设置为1时,如果MyISAM表中没有空洞(即表的中间没有被删除的行),MyISAM允许在一个进程读表的同时,另一个进程从表尾插入记录。这也是MySQL的默认设置。
    • 当concurrent_insert设置为2时,无论MyISAM表中有没有空洞,都允许在表尾并发插入记录。

    1.4、MyISAM的锁调度

    前面讲过,MyISAM存储引擎的读锁和写锁是互斥的,读写操作是串行的。那么,一个进程请求某个 MyISAM表的读锁,同时另一个进程也请求同一表的写锁,MySQL如何处理呢?

    答案是:写进程先获得锁

    不仅如此,即使读请求先到锁等待队列,写请求后到,写锁也会插到读锁请求之前!

    **这是因为MySQL认为写请求一般比读请求要重要。**这也正是MyISAM表不太适合于有大量更新操作和查询操作应用的原因,因为,大量的更新操作会造成查询操作很难获得读锁,从而可能永远阻塞。这种情况有时可能会变得非常糟糕!

    幸好我们可以通过一些设置来调节MyISAM 的调度行为。

    2、InnoDB的行锁模式及加锁模式

    2.1、InnoDB中的锁

    InnoDB实现了以下两种类型的行锁。

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-7Y9Qa2Kz-1581743638787)(images/02.png)]

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-3UrQW8iP-1581743638788)(images/03.png)]

    如果一个事务请求的锁模式与当前的锁兼容,InnoDB就将请求的锁授予该事务;反之,如果两者不兼容,该事务就要等待锁释放。

    2.2、锁的使用

    意向锁是InnoDB自动加的,不需用户干预; 对于UPDATEDELETEINSERT语句,InnoDB会自动给涉及数据集加排他锁(X);对于普通SELECT语句,InnoDB不会加任何锁;事务可以通过以下语句显示给记录集加共享锁或排他锁。

    共享锁(S):SELECT * FROM table_name WHERE ... LOCK IN SHARE MODE

    排他锁(X):SELECT * FROM table_name WHERE ... FOR UPDATE

    SELECT ... IN SHARE MODE获得共享锁,主要用在需要数据依存关系时来确认某行记录是否存在,并确保没有人对这个记录进行UPDATE或者DELETE操作。但是如果当前事务也需要对该记录进行更新操作,则很有可能造成死锁,对于锁定行记录后需要进行更新操作的应用,应该使用SELECT… FOR UPDATE方式获得排他锁。

    2.3、InnoDB行锁实现方式

    InnoDB行锁是通过索引上的索引项来枷锁实现的

    在实际应用中,需要特别注意InnoDB行锁的这一特性,不然的话,可能导致大量的锁冲突,从而影响并发性能

    • 在不通过索引条件查询的时候,InnoDB确实使用的是表锁,而不是行锁
    • 由于MySQL的行锁是针对索引加的锁不是针对记录加的锁,所以虽然是访问不同行的记录,但是如果是使用相同的索引键,是会出现锁冲突的
    • 当表有多个索引的时候,不同的事务可以使用不同的索引锁定不同的行,另外,不论是使用主键索引、唯一索引或普通索引

    2.4、间隙锁(Next-Key锁)

    当我们用范围条件而不是相等条件检索数据,并请求共享或排他锁时,InnoDB会给符合条件的已有数据记录的索引项加锁;对于键值在条件范围内但并不存在的记录,叫做“间隙(GAP)”,InnoDB也会对这个“间隙”加锁,这种锁机制就是所谓的间隙锁(Next-Key锁)。

    /*举例来说,假如emp表中只有101条记录,其empid的值分别是 1,2,...,100,101,下面的SQL:*/
    Select * from  emp where empid > 100 for update;
    /*是一个范围条件的检索,InnoDB不仅会对符合条件的empid值为101的记录加锁,也会对empid大于101(这些记录并不存在)的“间隙”加锁。*/
    
    

    InnoDB使用间隙锁的目的,一方面是为了防止幻读,以满足相关隔离级别的要求,对于上面的例子,要是不使用间隙锁,如果其他事务插入了empid大于100的任何记录,那么本事务如果再次执行上述语句,就会发生幻读;另外一方面,是为了满足其恢复和复制的需要

    很显然,在使用范围条件检索并锁定记录时,InnoDB这种加锁机制会阻塞符合条件范围内键值的并发插入,这往往会造成严重的锁等待。因此,在实际应用开发中,尤其是并发插入比较多的应用,我们要尽量优化业务逻辑,尽量使用相等条件来访问更新数据,避免使用范围条件。

    3、事务

    3.1、事务及其ACID属性

    事务是由一组SQL语句组成的逻辑处理单元,事务具有以下4个属性,通常简称为事务的ACID属性

    ACID属性

    • 原子性(Atomicitity):事务是由一个原子操作单元,其对数据的修改,要么全执行,要么全部执行
    • 一致性(Consistent):在事务开始和完成时,数据都必须保持一致状态。这意味着所有相关的数据规则都必须因应用于事务的修改,以保持数据的完整性;事务结束时,所有的内部数据结构(如B树索引和双向链表)也都必须是正确的。
    • 隔离型(Isolation):数据库系统提供一定的隔离机制,保证事务在不受外部并发操作影响的独立环境执行。这意味着事务处理过程中的中间状态对外部是不可见的
    • 持久性(Durable):事务完成之后,它对于数据的修改时永久性的,即使出现系统故障也能够保持。

    3.2、并发事务处理带来的问题

    相对于串行处理来说,并发事务处理能大大增加数据库资源的利用率,提高数据库系统的事务吞吐量,从而可以支持更多的用户。但并发事务处理也会带来一些问题,主要包括以下几种情况。

    • 更新丢失当两个或多个事务选择同一行,然后基于最初选定的值更新该行时,由于每个事务都不知道其他事务的存在,就会发生丢失更新问题--最后的更新覆盖了由其他事务所做的更新

    • 脏读一个事务正在对一条记录做修改,在这个事务完成并提交前,这条记录的数据就处于不一致状态;这时,另一个事务也来读取同一条记录,如果不加控制,第二个事务读取了这些“脏”数据,并据此做进一步的处理,就会产生未提交的数据依赖关系。这种现象被形象地叫做"脏读"

    • 不可重复读:**一个事务在读取某些数据后的某个时间,再次读取以前读过的数据,却发现其读出的数据已经发生了改变、或某些记录已经被删除了!这种现象就叫做“不可重复读”。 **

    • 幻读一个事务按相同的查询条件重新读取以前检索过的数据,却发现其他事务插入了满足其查询条件的新数据,这种现象就称为“幻读”

      note: 不可重复读和幻读本质上是一样的,就是一个事务内两次读取同样的数据,结果不一样;这就是统一的欢度问题;行级锁可以解决更新删除导致的幻读间隙锁可以解决插入导致的幻读

    3.3、事务的隔离级别

    为了解决上述的问题:

    在上面讲到的并发事务处理带来的问题中,==“更新丢失”==通常是应该完全避免的。但防止更新丢失,并不能单靠数据库事务控制器来解决,需要应用程序对要更新的数据加必要的锁来解决,因此,防止更新丢失应该是应用的责任。

    “脏读”、“不可重复读”和“幻读”,其实都是数据库读一致性问题必须由数据库提供一定的事务隔离机制来解决

    数据库实现事务隔离的方式,基本上可分为以下两种。

    • 一种是在读取数据前,对其加锁,阻止其他事务对数据进行修改。
    • 另一种是不用加任何锁,通过一定机制生成一个数据请求时间点的一致性数据快照(Snapshot),并用这个快照来提供一定级别(语句级或事务级)的一致性读取。从用户的角度来看,好像是数据库可以提供同一数据的多个版本,因此,这种技术叫做数据多版本并发控制(MultiVersion Concurrency Control,简称MVCC或MCC),也经常称为多版本数据库。

    为了解决“隔离”与“并发”的矛盾,ISO/ANSI SQL92定义了4个事务隔离级别,每个级别的隔离程度不同,允许出现的副作用也不同,应用可以根据自己的业务逻辑要求,通过选择不同的隔离级别来平衡 “隔离”与“并发”的矛盾。下表很好地概括了这4个隔离级别的特性。

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-r8PpV9p9-1581743638789)(images/01.png)]

    展开全文
  • Mysql行锁和表锁区别

    2021-07-05 11:02:09
    MYISAM不支持行锁,而InnoDB支持行锁和表锁。 1.行锁和表锁 在mysql 的 InnoDB引擎支持行锁,与Oracle不同,mysql的行锁是通过索引加载的,即是行锁是加在索引响应的行上的,要是对应的SQL语句没有走索引,则会全表...

    mysql常用引擎有MYISAM和InnoDB,而InnoDB是mysql默认的引擎。MYISAM不支持行锁,而InnoDB支持行锁和表锁。

    1.行锁和表锁

    在mysql 的 InnoDB引擎支持行锁,与Oracle不同,mysql的行锁是通过索引加载的,即是行锁是加在索引响应的行上的,要是对应的SQL语句没有走索引,则会全表扫描,行锁则无法实现,取而代之的是表锁。
    表锁:不会出现死锁,发生锁冲突几率高,并发低。
    行锁:会出现死锁,发生锁冲突几率低,并发高。

    锁冲突:例如说事务A将某几行上锁后,事务B又对其上锁,锁不能共存否则会出现锁冲突。(但是共享锁可以共存,共享锁和排它锁不能共存,排它锁和排他锁也不可以)
    死锁:例如说两个事务,事务A锁住了15行,同时事务B锁住了610行,此时事务A请求锁住610行,就会阻塞直到事务B施放610行的锁,而随后事务B又请求锁住15行,事务B也阻塞直到事务A释放15行的锁。死锁发生时,会产生Deadlock错误。
    锁是对表操作的,所以自然锁住全表的表锁就不会出现死锁。

    2.行锁的类型

    行锁分 共享锁 和 排它锁。
    共享锁又称:读锁。当一个事务对某几行上读锁时,允许其他事务对这几行进行读操作,但不允许其进行写操作,也不允许其他事务给这几行上排它锁,但允许上读锁。
    排它锁又称:写锁。当一个事务对某几个上写锁时,不允许其他事务写,但允许读。更不允许其他事务给这几行上任何锁。包括写锁。
    上共享锁的写法:lock in share mode

    例如: select  math from zje where math>60 lock in share mode;
    

    上排它锁的写法:for update

    例如:select math from zje where math >60 for update;
    

    3.行锁的实现.

    注意几点:
    1.行锁必须有索引才能实现,否则会自动锁全表,那么就不是行锁了。
    2.两个事务不能锁同一个索引,例如:

    事务A先执行:  
    select math from zje where math>60 for update;  
    事务B再执行:  
    select math from zje where math<60 for update;  
    这样的话,事务B是会阻塞的。如果事务B把 math索引换成其他索引就不会阻塞,但注意,换成其他索引锁住的行不能和math索引锁住的行有重复。  
    

    3.insert ,delete , update在事务中都会自动默认加上排它锁。
    会话1:

    begin;
    select  math  from zje where math>60 for update;	
    

    会话2:

    begin;
    update zje set math=99 where math=68;
    阻塞...........
    

    会话相当与用户
    如上,会话1先把zje表中math>60的行上排它锁。然后会话2试图把math=68的行进行修改,math=68处于math>60中,所以是已经被锁的,会话2进行操作时,
    就会阻塞,等待会话1把锁释放。当commit时或者程序结束时,会释放锁。

    展开全文
  • 对于行锁和表锁的含义区别,在面试中应该是高频出现的,我们应该对MySQL中的锁有一个系统的认识,更详细的需要自行查阅资料,本篇为概括性的总结回答。 MySQL常用引擎有MyISAMInnoDB,而InnoDB是mysql默认的引擎。...
  • 看见别人的好文章,转载下,学习下,原文地址:...mysql常用引擎有MYISAMInnoDB,而InnoDB是mysql默认的引擎。MYIS
  • oracle行锁和表锁

    2021-10-21 13:59:35
    行锁,是锁住具体某一个行货几行,其他的数据是可以访问的 如果添加where条件,只会锁行,这个索引没有关系,都是锁行(oracle测试是这样) update ESTATE_DJ_AJXX t set ywh='3' where id='1' 更新,这是表锁,...
  • 对于行锁和表锁的含义区别,在面试中应该是高频出现的,我们应该对MySQL中的锁有一个系统的认识,更详细的需要自行查阅资料,本篇为概括性的总结回答。 MySQL常用引擎有MyISAMInnoDB,而InnoDB是mysql默认的引擎。...
  • 对于行锁和表锁的含义区别,在面试中应该是高频出现的,我们应该对MySQL中的锁有一个系统的认识,更详细的需要自行查阅资料,本篇为概括性的总结回答。 MySQL常用引擎有MyISAMInnoDB,而InnoDB是mysql默认的引擎...
  • 这个时候发现,虽然窗口 A B 更新的行不一样,但是窗口 B 还是被阻塞住了,就是因为窗口 A 的索引失效,导致行锁升级成了表锁,把整个表锁住了,索引窗口 B 被阻塞了。 窗口 A 执行 commit 操作 可以看到这个...
  • 程序员的成长之路互联网/程序员/技术/资料共享关注阅读本文大概需要 4分钟。来自:网络一、前言对于行锁和表锁的含义区别,在面试中应该是高频出现的,我们应该对MySQL中的锁有一个系统...
  • 从对数据的操作粒度分为:表锁 行锁 表锁 表锁特点 MylSAM引擎使用表锁,开销小,加锁快,无死锁,锁定力度大,发生锁冲突的概率最高。 并发度最低 不支持事务 查看数据库锁 SHOW OPEN TABLES in hanyxx; --...
  • 细谈数据库表锁和行锁

    万次阅读 多人点赞 2019-09-19 21:59:00
    表锁1. 特点2. MDL元数据锁(metadata lock)1. 特点3. MDL锁的坑————给一个小表加字段1. 问题描述3. online ddl(ddl:更改表结构)3. 行锁1. 行锁特性2. 两阶段锁协议4. 死锁1. 处理死锁策略2. 死锁检测(⭐...
  • 数据库for update是行锁还是表锁

    千次阅读 2019-08-05 09:19:57
    当使用select … for update …where …时,mysql进行row lock还是table lock只取决于是否能使用索引(例如主键,unique字段),能则为行锁,否则为表锁;未查到数据则无锁。而 使用’<>’,'like’等操作时,...
  • Mysql InnoDB引擎的行锁和表锁

    万次阅读 多人点赞 2018-08-14 22:55:29
    1.行锁和表锁 在mysql 的 InnoDB引擎支持行锁,与Oracle不同,mysql的行锁是通过索引加载的,即是行锁是加在索引响应的行上的,要是对应的SQL语句没有走索引,则会全表扫描, 行锁则无法实现,取而代之的是...
  • 对于行锁和表锁的含义区别,在面试中应该是高频出现的,我们应该对MySQL中的锁有一个系统的认识,更详细的需要自行查阅资料,本篇为概括性的总结回答。 MySQL常用引擎有MyISAMInnoDB,而InnoDB是mysql默认的引擎...
  • mysql数据库行锁表锁解析一般而言 表锁发生的情况不会影响表的查询操作 只对写入会有限制,例如select * from tableName for update 并且没有commit的时候会产生表级锁。行锁发生的条件为操作时有条件语句 并且...
  • mysql innodb行锁表锁、意向锁

    千次阅读 2019-09-06 11:19:15
    今天讲一下mysql的数据库引擎中的InnoDb下的行锁表锁、意向锁等 行锁 mysql的行锁是通过索引加载的,即是行锁是加在索引响应的行上的,要是对应的SQL语句没有走索引,则会全表扫描 行锁类型 共享锁 排它锁 ...
  • Mysql锁分为表锁和行锁,表锁虽然开销小,锁表快,但高并发下性能低。行锁虽然开销大,锁表慢,但是并发性能高。InnoDB采用的行锁,支持事务;MyISAM采用表锁不支持事务 InnoDB行锁会变表锁吗? 案例分析: 创建表...
  • MySQL行锁表锁特点应用场景

    千次阅读 2019-11-11 15:22:03
    Mysql不同的存储引擎支持的不同的锁。 ...行锁和表锁 行锁:访问数据库时锁定整个行数据,防止并发错误。 表锁:访问数据库时锁定整个表数据,防止并发错误。 区别: 行锁:锁力度小,开销...
  • 1 数据库锁定机制简单来说, 就是数据库为了保证数据的一致性, 而使各种共享资源在被 并发访问变得 有序所设计的一种规则. 2 行级锁定 (row-level). 使用行级锁定的主要是 InnoDB 存储引擎. 行级锁定最大的特点就是...
  • Mysql的行锁和表锁

    2020-04-26 20:59:30
    InnoDB 的行锁,就是通过锁住索引来实现的
  • Innodb 行锁表锁

    2020-12-22 10:44:51
    行锁表锁 InnoDB默认是行级别的锁,当有明确指定的主键时候,是行级锁。否则是表级别。 #for update的注意点for update 仅适用于InnoDB,并且必须开启事务,在begin与commit之间才生效。 要测试for update的锁...
  • 事务的隔离级别为:可重复读时, 如果有索引(包括主键索引),以索引列为条件更新数据,会存在间隙锁,行锁,页锁,而锁住一些行。 如果没有索引,更新数据时会锁住整张表。 ...
  • 表锁2.1.1. 特点2.2. MDL元数据锁(metadata lock)2.2.1. 特点2.3. MDL锁的坑————给一个小表加字段2.3.1. 问题描述2.3.2. 解决方法2.3.3. online ddl(ddl:更改表结构)3. 行锁3.1. 行锁特性3.2. 两阶段锁...
  • Innodb的行锁和表锁

    2021-01-17 17:07:25
    什么是行锁和表锁? 行锁:对一个表锁住某几行,其他事务对锁住的行不能进行写操作. 表锁:锁住整个表,其他事务对整个表不能进行写操作. 注意:这两个锁都是针对于事务来说的,没有开启事务或者是在一个事务里面也就不...
  • 数据库行锁表锁

    千次阅读 2018-10-14 23:35:26
    可参考 https://blog.csdn.net/nicajonh/article/details/78814987

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 33,164
精华内容 13,265
关键字:

数据库的行锁和表锁