首页 > 数据库 >Mysql四种事务隔离级别

Mysql四种事务隔离级别

时间:2023-04-12 22:08:08浏览次数:45  
标签:log account 隔离 事务 user Mysql 四种 客户端


先了解一下事务的四大特性:ACID

原子性(Atomicity)

原子性就是不可拆分的特性,要么全部成功然后提交(commit),要么全部失败然后回滚(rollback)。MySQL通过Redo Log重做日志实现了原子性,在将执行SQL语句时,会先写入redo log buffer,再执行SQL语句,若SQL语句执行出错就会根据redo log buffer中的记录来执行回滚操作,由此拥有原子性。

一致性(Consistency)

一致性指事务将数据库从一种状态转变为下一种一致的状态。比如有一个字段name有唯一索引约束,那么在事务前后都不能有重复的name出现违反唯一索引约束,否则回滚。MySQL通过undo Log实现一致性,执行SQL语句时,会先写入undo log再写入 redo log buffer。undo是逻辑日志,会根据之前的SQL语句进行相应回滚,并且除了回滚,undo log还有一个作用是MVCC,当用户读取一行记录时,若该记录已经被其他事务占用,当前事务可通过undo读取之前的行版本信息,实现非锁定读取。并且undo log也会产生redo log,因为undo log也需要持久性的保护。

隔离性(Isolation)

如果没有隔离性会发生如下问题:

1,数据丢失:A事务撤销时,把已经提交的B事务的更新数据覆盖了。

2,脏读:脏读主要是读取到了其他事务的数据,而其他事务随后发生回滚。MySQL通过三级封锁协议的第二级解决了脏读,在一级的基础上,要求读取数据 A 时必须加 S 锁,读取完马上释放 S 锁。

3,不可重复读:不可重复读是读取到数据后,随后其他事务对数据发生了修改,无法再次读取。MySQL通过三级封锁协议的第三级解决了不可重复读。在二级的基础上,要求读取数据 A 时必须加 S 锁,直到事务结束了才能释放 S 锁。

4,幻读:幻读是读取到数据后,随后其他事务对数据发生了新增,无法再次读取。在InnoDB引擎Repeatable Read的隔离级别下,MySQL通过Next-Key Lock以及MVCC解决了幻读,事务中分为当前读以及快照读。

  • 快照读(snapshot read) ——通过MVCC来避免幻读
    简单的select操作(不包括 select … lock in share mode, select … for update)
  • 当前读(current read) ——通过Next-Key Lock 来避免幻读 Next-Key Lock即间隙锁(Gap Lock)+行锁 (Record Lock);

持久性(Durability)

一旦事务提交,则其所做的修改就会永久保存到数据库中。此时即使系统崩溃,修改的数据也不会丢失。具体实现原理就是在事务commit之前会将,redo log buffer中的数据持久化到硬盘中的redo log file,这样在commit的时候,硬盘中已经有了我们修改或新增的数据,由此做到持久化。

 

Mysql的四大隔离级别

区别

Mysql四种事务隔离级别_回滚

Mysql默认隔离级别REPEATABLE-READ

Mysql四种事务隔离级别_回滚_02

演示四大隔离级别

建表语句

DROP TABLE IF EXISTS `user_account`;
CREATE TABLE `user_account` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `user_id` int(11) NOT NULL,
  `balance` int(11) NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8;

当前环境和版本

Mysql四种事务隔离级别_回滚_03

读未提交read-uncommit

打开一个客户端A,并设置当前事务模式为read uncommitted(未提交读),查询表user_account的初始值:

Mysql四种事务隔离级别_客户端_04

在客户端A的事务提交之前,打开另一个客户端B,更新表user_account:

Mysql四种事务隔离级别_回滚_05

此时在回到客户端A查询数据结果为:

Mysql四种事务隔离级别_客户端_06

这时候客户端B事务还没有提交,然后客户端A就能查到数据客户端B更新的数据了。那么一旦客户端B执行(ROLLBACK)回滚了事务,那么此时就会导致客户端A的数据脏读。

提交已读(read-commit)

打开一个客户端A,并设置当前事务模式为read committed(读已提交),查询表user_account的所有记录:

Mysql四种事务隔离级别_客户端_07

在客户端A的事务提交之前,打开另一个客户端B,更新表user_account并提交;

Mysql四种事务隔离级别_回滚_08

在客户端A查询表account的所有记录,与步骤(1)查询结果一致,没有出现不可重复读的问题

Mysql四种事务隔离级别_数据_09

可重复读(repeatable-read)

打开一个客户端A,并设置当前事务模式为repeatable read,查询表user_account的所有记录

Mysql四种事务隔离级别_回滚_10

在客户端A的事务提交之前,打开另一个客户端B,更新表user_account并提交

Mysql四种事务隔离级别_数据_11

在客户端A查询表user_account的所有记录,与客户端执行事务之前查询结果一致,没有出现不可重复读的问题

Mysql四种事务隔离级别_回滚_12

在客户端B插入一条数据

Mysql四种事务隔离级别_客户端_13

在客户端A中还是没有数据

Mysql四种事务隔离级别_回滚_14

串行化(serializable)

打开一个客户端A,并设置当前事务模式为serializable,查询表user_account的初始值:

Mysql四种事务隔离级别_回滚_15

打开一个客户端B,并设置当前事务模式为serializable,插入一条记录报错,表被锁了插入失败,mysql中事务隔离级别为serializable时会锁表,因此不会出现幻读的情况,这种隔离级别并发性极低,开发中很少会用到

Mysql四种事务隔离级别_客户端_16

补充:

1、事务隔离级别为读提交时,写数据只会锁住相应的行

2、事务隔离级别为可重复读时,如果检索条件有索引(包括主键索引)的时候,默认加锁方式是next-key 锁;如果检索条件没有索引,更新数据时会锁住整张表。一个间隙被事务加了锁,其他事务是不能在这个间隙插入记录的,这样可以防止幻读。

3、事务隔离级别为串行化时,读写数据都会锁住整张表

4、隔离级别越高,越能保证数据的完整性和一致性,但是对并发性能的影响也越大。


标签:log,account,隔离,事务,user,Mysql,四种,客户端
From: https://blog.51cto.com/u_11702014/6186300

相关文章

  • Mysql 入门之过滤数据(一)
    关键字:where、between、null知识点1、where关键字在Mysql中用于获取指定搜素条件的数据,这些条件也称之为过滤条件2、between为where子句的操作符,诸如=、<、>等符号功能类似3、关于null可以初步理解为它是Mysql中不确定的“值”,从根本上讲它都不是个“值”下面给出一些案......
  • cnetos8上RPM安装mysql8后,修改初始密码提示Your password does not satisfy the curre
    我在修改mysql8初始密码是遇到了Yourpassworddoesnotsatisfythecurrentpolicyrequirements,如果您的mysql版本5.x可能不太合适。下图是我遇到的问题: 意思是,密码不符合密码验证要求。但是mysql8的初始密码连验证要求都查不到,不过一般密码强度是不过我们可以密码设置为......
  • mysql性能优化二
    索引:高校检索数据的数据结构索引能干吗呢‘?索引在MySQL中也叫做“键”,是存储引擎用于快速找到记录的一种数据结构。索引对于良好的性能非常关键,尤其是当表中的数据量越来越大时,索引对于性能的影响愈发重要。索引优化应该是对查询性能优化最有效的手段了。索引能够轻易将查询性能提......
  • 4-20ma输入0-10v输出模拟量电流转换电压隔离模块
    主要特性:⑴精度等级:0.1级、0.2级、0.5级。产品出厂前已检验校正,用户可以直接使用⑵辅助电源:5V/12V/15V/24VDC或者220VAC(范围±10%)⑶国际标准二路信号输入:0-5V/0-10V/1-5V,0-10mA/0-20mA/4-20mA等⑷二路输出标准信号:0-5V/0-10V/1-5V,0-10mA/0-20mA/4-20mA等,具有高负载能力⑸全量......
  • centos安装MySQL8记录
    1.卸载mariadb因centos7默认安装了mariadb,会造成依赖冲突,按下列方式进行卸载:rpm-qa|grepmariadb#如果出现mariadb-libs-5.5.68-1.el7.x86_64#执行rpm-emariadb-libs--nodeps2.下载  注意权限:(chmod-R777/var/lib/mysql)(chmod-R777/var......
  • mysql查询过程优化--理论及实践过程总结
    首先推荐一篇写的特别详细的帖子,感觉写的太好了。全看懂了,就不用看我下面的废话了。https://blog.52ipc.top/archives/149.html然后记录点自己解决的经验正式开始写一下我的优化过程:问题:MySQL查询count()from(括号里有七八个leftjoin),导致查询速度特别慢,结果大概是40s+1、......
  • python之封装mysql
     数据查询类封装1.功能分析可以连接不同sql数据库查一条数据,多条数据可以获取不同格式的数据2.封装成数据库查询类封装思路:数据库查询模块有多个功能,且需要复用,所以封装成类在构造方法中创建连接创建对象方法实现各种查询#-*-coding:utf-8-*-#@Time......
  • 漏洞-Oracle MYSQL Server 安全漏洞(CVE-2022-1292)
    https://blog.csdn.net/weixin_45839894/article/details/126158078openssl:relocationerror:openssl:symbolEVP_mdc2versionOPENSSinedinfilelibcrypto.so.1.1withlinktimereference建议先删掉/usr/bin/openssl......
  • mysql insert|replace语法
    insert语法replace语法版权声明:本文所有权归作者!商业用途转载请联系作者授权!非商业用途转载,请标明本文链接及出处!赞成、反驳、不解的小伙伴,欢迎一起交流!......
  • mysql 使用分区partition_name 作为条件查询
       SELECT*FROMmy_tablePARTITION(partition_name)WHEREcolumn_name='value';```将`my_table`替换为您的表名,将`partition_name`替换为您要查询的分区的名称,将`column_name`替换为您要用作条件的列的名称,将`'value'`替换为您要用作过滤器的值。......