资讯专栏INFORMATION COLUMN

MySql 事物及隔离级别

XFLY / 898人阅读

摘要:二事务的四种隔离级别在数据库操作中,为了有效保证并发读取数据的正确性,提出的事务隔离级别。在可重读事务隔离级别下时,读取创建版本号当前事务版本号,删除版本号为空或当前事务版本号。

一、事务的基本要素(ACID)

  1、原子性(Atomicity):事务开始后所有操作,要么全部做完,要么全部不做,不可能停滞在中间环节。事务执行过程中出错,会回滚到事务开始前的状态,所有的操作就像没有发生一样。也就是说事务是一个不可分割的整体,就像化学中学过的原子,是物质构成的基本单位。

   2、一致性(Consistency):事务开始前和结束后,数据库的完整性约束没有被破坏 。比如A向B转账,不可能A扣了钱,B却没收到。

   3、隔离性(Isolation):同一时间,只允许一个事务请求同一数据,不同的事务之间彼此没有任何干扰。比如A正在从一张银行卡中取钱,在A取钱的过程结束前,B不能向这张卡转账。

   4、持久性(Durability):事务完成后,事务对数据库的所有更新将被保存到数据库,不能回滚。

二、事务的四种隔离级别
在数据库操作中,为了有效保证并发读取数据的正确性,提出的事务隔离级别。我们的数据库锁,也是为了构建这些隔离级别存在的。
隔离级别 脏读(Dirty Read) 不可重复读(NonRepeatable Read) 幻读(Phantom Read)
未提交读(Read uncommitted) 可能 可能 可能
已提交读(Read committed) 不可能 可能 可能
可重复读(Repeatable read) 不可能 不可能 可能
可串行化(Serializable ) 不可能 不可能 不可能

未提交读(Read Uncommitted):允许脏读,也就是可能读取到其他会话中未提交事务修改的数据

提交读(Read Committed):只能读取到已经提交的数据。Oracle等多数数据库默认都是该级别 (不重复读)

可重复读(RepeatedRead):可重复读。在同一个事务内的查询都是事务开始时刻一致的,InnoDB默认级别。在SQL标准中,该隔离级别消除了不可重复读,但是还存在幻象读。mysql默认级别:可重复读

串行读(Serializable):完全串行化的读,每次读都需要获得表级共享锁,读写相互都会阻塞

三、事务的并发问题

  1、脏读:事务A读取了事务B更新的数据,然后B回滚操作,那么A读取到的数据是脏数据

  2、不可重复读:事务 A 多次读取同一数据,事务 B 在事务A多次读取的过程中,对数据作了更新并提交,导致事务A多次读取同一数据时,结果 不一致。

  3、幻读:系统管理员A将数据库中所有学生的成绩从具体分数改为ABCDE等级,但是系统管理员B就在这个时候插入了一条具体分数的记录,当系统管理员A改结束后发现还有一条记录没有改过来,就好像发生了幻觉一样,这就叫幻读。

  小结:不可重复读的和幻读很容易混淆,不可重复读侧重于修改,幻读侧重于新增或删除。解决不可重复读的问题只需锁住满足条件的行,解决幻读需要锁表。

四、MVCC在MySQL的InnoDB中的实现

在InnoDB中,会在每行数据后添加两个额外的隐藏的值来实现MVCC,这两个值一个记录这行数据何时被创建,另外一个记录这行数据何时过期(或者被删除)。 在实际操作中,存储的并不是时间,而是事务的版本号,每开启一个新事务,事务的版本号就会递增。 在可重读Repeatable reads事务隔离级别下:

SELECT时,读取创建版本号<=当前事务版本号,删除版本号为空或>当前事务版本号。

INSERT时,保存当前事务版本号为行的创建版本号。

DELETE时,保存当前事务版本号为行的删除版本号。

UPDATE时,插入一条新纪录,保存当前事务版本号为行创建版本号,同时保存当前事务版本号到原来删除的行。

通过MVCC,虽然每行记录都需要额外的存储空间,更多的行检查工作以及一些额外的维护工作,但可以减少锁的使用,大多数读操作都不用加锁,读数据操作很简单,性能很好,并且也能保证只会读取到符合标准的行,也只锁住必要行。

我们不管从数据库方面的教课书中学到,还是从网络上看到,大都是上文中事务的四种隔离级别这一模块列出的意思。

MVCC 总结:为了实现快照读(读写不冲突)

五 MySQL死锁

死锁是只两个或者多个事务在同一个资源上相互占用,并请求锁定对方占用的资源。从而导致循环的现象。当多个事务试图以不同的顺序锁定资源时,就可能产生死锁。多个事务同事锁定同一个资源时,也会产生死锁。例如,两个事务同事处理stockprice表。

事务1:
    start transaction;
    update stockprice set close = 45.50 where stock_id = 4 and date = "2019-05-05";
    update stockprice set close = 36.66 where stock_id = 3 and date = "2019-05-06";
    commit
事务2:
    start transaction;
    update stockprice set high = 33.33 where stock_id = 3 and date = "2019-05-06";
    update stockprice set high = 35.66 where stock_id = 4 and date = "2019-05-05";
    commit
    

如果连个都执行了第一条update 语句,跟新了一行数据,同事也锁定了该行数据,接着每个事务都尝试去执行第二条update语句,发现该行已经被对方锁定,然后两个事务都等待对方释放锁,同事又持有对方需要的锁,则陷入死循环。除非有外部因素介入才能解除死锁。

六 EXPLAIN 分析语句
1. select_type:查询类型,
    1. simple:一般是简单查询,不使用union或子查询
    2. subquery:子查询中的第一个select
    3. primary:最外层的select
2. type:mysql找到所需行的方式,又叫“访问类型”,由差到好的顺序:
    1. type=ALL:全表扫描(一般需要进行优化)
    2. type=index:整个索引扫描(不满足最左匹配可能会引起)
    3. type=range:使用一个索引来检索给定范围的行
    4. type=ref:mysql会根据特定的算法快速查找到某个符合条件的索引,而不是会对索引中每一个数据都进行一一的扫描判断
    5. type=eq_ref:类似ref,区别是使用的索引是唯一索引
    6. const、system:常量匹配,主键匹配
3. rows:找到所需记录需要读取的行数(估计值)
4. extra:详细信息,常见:
    1. Using index:只查询索引就能得到结果(覆盖索引)
    2. Using where:需要通过索引再检索实际数据进行过滤
    3. Using temporary:使用临时表
    4. Using filesort:使用临时文件排序
    
七 锁的定义

1.每次总是被什么共享锁、排他锁给绕晕了。简单实际一点。就只有 读锁 写锁 两种锁。对应关系如下:

锁类型 描述
共享锁(读锁 其他事务可以读,但不能写。
排他锁(写锁) 其他事务不能读取,也不能写。

2.乐视锁和悲观锁

乐观锁:是一种解决问题的逻辑。采用版本号的处理方式实现

悲观锁:是借用mysql InnoDB 行锁来实现的(where 条件必须要加索引)。

select * from user whereid = 10 for update

3.行锁和表锁

行锁:顾名思义就是锁定每一行

表锁:顾名思义就是锁定整张表

4.其他mysql 内部实现的锁机制

隐式锁、间隙锁等。

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/49049.html

相关文章

  • 【全栈之路】JAVA基础课程八_Mysql事物隔离级别(20190624v1.0)

    摘要:注意不仅可以控制事务传播行为等,还可以控制事务隔离级别等。事物的隔离级别隔离级别越高,并发性能越低。在的隔离级别下,会出现幻读的问题。可串行化是最高的隔离级别。 欢迎进入JAVA基础课程 博客地址:https://mp.csdn.net/mdeditor/...本系列文章将主要针对JAVA一些基础知识点进行讲解,为平时归纳所总结,不管是刚接触JAVA开发菜鸟还是业界资深人士,都希望对...

    niuxiaowei111 评论0 收藏0
  • 【全栈之路】JAVA基础课程八_Mysql事物隔离级别(20190624v1.0)

    摘要:注意不仅可以控制事务传播行为等,还可以控制事务隔离级别等。事物的隔离级别隔离级别越高,并发性能越低。在的隔离级别下,会出现幻读的问题。可串行化是最高的隔离级别。 欢迎进入JAVA基础课程 博客地址:https://mp.csdn.net/mdeditor/...本系列文章将主要针对JAVA一些基础知识点进行讲解,为平时归纳所总结,不管是刚接触JAVA开发菜鸟还是业界资深人士,都希望对...

    tinysun1234 评论0 收藏0
  • 【全栈之路】JAVA基础课程八_Mysql事物隔离级别(20190624v1.0)

    摘要:注意不仅可以控制事务传播行为等,还可以控制事务隔离级别等。事物的隔离级别隔离级别越高,并发性能越低。在的隔离级别下,会出现幻读的问题。可串行化是最高的隔离级别。 欢迎进入JAVA基础课程 博客地址:https://mp.csdn.net/mdeditor/...本系列文章将主要针对JAVA一些基础知识点进行讲解,为平时归纳所总结,不管是刚接触JAVA开发菜鸟还是业界资深人士,都希望对...

    twohappy 评论0 收藏0
  • mysql 事物浅析

    摘要:事物是什么书上说事物作为一个不可分割的逻辑单元而被执行的一组语句,如果有必要,他们的执行效果可以被撤销。我的理解上面的这段话是技术内幕对事物所下的定义。的主要作用,就是挂起自动提交模式。 事物是什么? 书上说:事物作为一个不可分割的逻辑单元而被执行的一组sql语句,如果有必要,他们的执行效果可以被撤销。我的理解:上面的这段话是《mysql技术内幕》对事物所下的定义。好高大上的样子,似...

    Coding01 评论0 收藏0
  • MySql优化那些事

    摘要:但在中,除单个组成的事务外,锁是逐步获得的,当两个事务都需要获得对方持有的排他锁才能继续完成事务,这种循环锁等待就是典型的死锁。 MySql如何工作 Mysql客户端和服务器之间的通信协议是半双工的,意味着在任何一个时刻,要么是由服务器向客户端发送数据,要么是有客户端向服务器发送数据,这两个动作不能同时发生。当我们发送一条SQL命令引擎时,MySql执行过程如下图所示showImg(h...

    Shisui 评论0 收藏0

发表评论

0条评论

XFLY

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<