美文网首页
mysql(innodb)学习笔记之锁

mysql(innodb)学习笔记之锁

作者: 一人_e0fb | 来源:发表于2018-04-24 14:32 被阅读22次

mysql(innodb)锁有两种:

共享锁(s):表示我正在读,你可以读(可以读表示加上s锁的读),但不能修改

排他锁(x):表示我正在修改,你不能读,也不能修改

单独的select语句(不去获得锁)可以执行,是因为读的是加锁或者事务前的快照版本

当然还有所谓的意向共享锁,意向排它锁,只是说上锁的数据由一行变成了多行,mysql中的锁可以看成java中的锁,在java里你只有获得了锁才能进入上锁的代码中,而mysql是你上锁后只有获得了锁才能进行相应的操作。

然后,innodb默认在修改语句上加了排它锁,也就是说

update t set a=1 where b=2

这样的语句其实真正是

select * from t where a =1 for update

update t set a=1 where b=2 

共享锁:

    共享锁是就像一起看一本书,我在看这一页,你也在看这一页,如果你想翻页什么的,就需要你和我都看完了这一页,不然肯定要打起来什么的了,当然,如果快看完的时候我表示想看上一页,你表示想看下一页,这要么就pk,要么就有一个人让步了,这就是死锁了,innodb默认解除死锁的方式是回滚较小的事务。

    例如 select * from t where a = 1 lock in share mode  ,后面的 lock in share mode  就是加上共享锁的意思了。共享的意思是分享,现在不是说是共享时代么,你想一下,共享单车之类的,每个人都可以用同一辆车,但是你如果想把这车变成自己的,我们就不同意了,这是公共的东西,也就是说你只能读,不能修改。就是说上锁后,其他其他人只能用,不能拿走或者改变它。

排他锁:

    排他锁的话就是类似于租东西,在租期内这东西为我所有,你不能看,不能拿,不能改,瞅都不给你瞅一眼。你想要的话,只有等我还了这东西你才能拿得到。

    例如  select * from t where a = 1 for update, 后面的 for update 就是加上排他锁的意思,排他,我想这不用我多解释了。真正感觉起来,排他锁就类似于悲观锁,任何人不管做什么是都会妨碍到我,所以一点都不让动。当然,如果这样的情况,张三借了A书,李四借了B书,张三准备还书前是准备借B书的,而李四还书前准备借A书,但是一看书被借走了,就一直没有还书,在等着其他人还书好去借。这种情况又是典型的死锁了,这就需要书店居中协调了,总要有个人先还书,大不了一个人就当没借过这个书,不要你的钱,当然,书店肯定是不要那个更少的钱,这也就是innodb默认解死锁的方式,回退较小的事务。

其他扩展:

    真的感觉锁就是一个意向或者是状态,上锁后就是一个加锁的状态,而加上锁时就是一个意向。

这些锁看起来并没有什么用,这就需要扩展了。当然这就牵扯到事务了

脏读:

    脏数据:缓冲池中被修改的数据,还没有提交。(事务的操作时在缓冲池中,提交了才写到磁盘中)

    脏读:一个事务可以读到另一个事务未提交的数据。。。违背了事务的隔离性

    事务的隔离性:事务间隔离开来,不能互相干扰,每个事务都应该感受不到另一个事务

不可重复读:

     不可重复读:一个事务读取同一记录两次但是数据不一样,即一个事务读取另一个事务提交的数据造成的结果,数据没有问题(数据已经写到磁盘),但是违反了事务的一致性。(与脏读区别为一个未提交(脏数据),一个已提交(有效数据))

    事务的一致性:事务开启时的状态应该和结束时的状态一致,如转账,能量守恒之类的。不可重复读,第一个事务的状态在第二个事务提交后已经改变。例如:a转账给b,但是中途另一个客户端把a转账给c了,状态已经改变(感觉也违反了隔离性)

虚读(幻读):

    虚读(幻读):一个事务更新了’全部数据‘,另一个事务插入了包含着’全部数据‘(一定条件的数据)里的数据,并提交,第一个事务这时候再提交,发现符合条件的数据并没有全部更新(跟不可重复读类似,只是虚读是删除和增加造成的,而不可重复读是修改造成的)

丢失更新:

    丢失更新:比如一个转账的业务,a用客户端转给b二十元,这时我们的想法肯定是开启个事务,

    update a set balance=balance-20 ,

    update b set balance=balance+20 

    再提交了吧,如果因为网络延迟,第一个事务在提交前,a用另一个客户端给b转了30块钱,这时又开了另一个事务,

    update a set balance=balance-30 ,

    update b set balance=balance+30 

    本来应该减50的,我们的想法是叠加,但最后要么减了三十,要么减了20,这是一个严重的问题

明白了这三个,然后就是事务的隔离级别了,很明显,

read_uncommited 读未提交。。。这样肯定就是会脏读了。

read_commited 读已提交,这样脏读肯定就没了,但是造成了不可重复读。

repeatable_read 可重复读,这样不可重复读没了,但是虚读没有解决。

serializable 序列化,这样的话,一切都解决了。但是一般我们不用这种,因为这是强制每个数据行的操作时同步进行的,效率太低了,那么这问题就来了,我们不用这种隔离级别,怎么防止虚读和丢失更新呢,虚读还好一点,丢失更新的话可能丢失的就不是一点点数据了。

这时候锁的用处就来了,加上个排他锁,或者自己实现一个乐观锁,比如在数据库中加个version的字段,更新是判断一下,更新完后version加一。

锁算法:

        record lock:单行记录锁

        gap lock : 范围锁,不包含记录本身

        next-key lock:锁定一个范围,并锁定记录本身

查看事务和锁的方法:

information_schema 数据库 中 innodb_trx ,innodb_locks ,innodb_lock_waits表 可以查看相应的事务和锁情况

相关文章

  • mysql(innodb)学习笔记之锁

    mysql(innodb)锁有两种: 共享锁(s):表示我正在读,你可以读(可以读表示加上s锁的读),但不能修改 ...

  • MySQL InnoDB 锁 学习笔记

    所在文集:数据库 本文的内容参考了: 架构师之路 - 挖坑,InnoDB的七种锁 架构师之路 - 插入InnoDB...

  • 淘宝MySQL文档整理

    MySQL · 引擎特性 · InnoDB 事务锁系统简介 MySQL · 引擎特性 · Innodb 锁子系统浅...

  • Innodb的锁

    Innodb的锁是行级锁 mysql delete是否会锁表 MySQL的InnoDB存储引擎支持行级锁,Inno...

  • MySQL系列之事务日志Redo log学习笔记

    MySQL系列之事务日志Redo log学习笔记 学习本博客之前需要储备知识: MySQL体系架构 InnoDB存...

  • InnoDB的锁机制

    笔记摘自《MYSQL技术内幕(InnoDB存储引擎)》 1 什么是锁 锁是数据库系统区别于文件系统的一个关键特性。...

  • 阿里P8大佬带你全面了解—MySQL锁:03.InnoDB行锁

    目录 InnoDB 行锁锁排查可以用的视图和数据字典InnoDB 行锁兼容性 InnoDB行锁之共享锁共享锁: 查...

  • InnoDB存储引擎的表的逻辑存储结构

    本文是《Mysql技术内幕--InnoDB存储引擎》的学习笔记。 本文主要内容是:介绍InnoDB的表的逻辑存储结...

  • Mysql

    MySQL InnoDB中使用悲观锁 要使用悲观锁,我们必须关闭mysql数据库的自动提交属性,因为MySQL默认...

  • Mysql存储引擎Innodb小结

    innodb是mysql支持事务的存储引擎,也是当前mysql默认的存储引擎。innodb支持行级别锁,对并发性事...

网友评论

      本文标题:mysql(innodb)学习笔记之锁

      本文链接:https://www.haomeiwen.com/subject/uofjlftx.html