MYSQL学习(二)

并发控制

  MySQL在两个层面实现并发控制:服务器层与存储引擎层。

读锁和写锁:

  在处理并发读或写时,可以通过实现一个由两种锁组成的系统来解决问题。

  这两种锁通常被称为共享锁和排他锁,或者称为读锁和写锁

  读锁:是共享的,或者说是相互不阻塞的,多个客户可以在同时读取同一数据。

  写锁:是排他的,一个写锁会阻塞其他的写锁和读锁,同一时刻只能有一个用户能够写入,并防止其他用户读取正在写入的数据。

锁粒度:

  锁粒度:指加锁的对象的大小。显然,锁的粒度越小,并发控制效率越高。

  锁的各种操作,包括获得锁、检查锁和释放锁等,都会增加系统开销。

  因此,如果系统花费大量时间来管理锁,而不是用来获取数据,就会影响系统性能。

  锁策略:在锁的开销和安全性之间寻求平衡。

  有两种常见的锁策略,表锁和行级锁

  表锁:开销较小,但是并发控制不好。

  行级锁:可以很好地实现并发控制,但是开销比较大。

  行级锁是在 mysql 的存储引擎层实现,没有在服务器层实现,innodb 中实现了行级锁。

1.3 事务

  事务:是一组原子性的SQL语句,事务内的语句,要么全部执行成功,要么全部执行失败。

事务的四大特性ACID

  原子性:整个事务要么全部提交成功,要么全部失败回滚,不可以只执行一部分。

  一致性:数据库总是从一个一致状态转换到另一个一致状态。(转账失败后,卡里的钱应该不变,不能少了)

  隔离性:事务提交之前所做的修改对其他事务是不可见的。(通常来说)

  持久性:事务提交之后,所做的修改会持久化到数据库中。

  事务处理也会使系统做更多额外工作,用户可以根据业务是否需要进行事务处理,选择合适的存储引擎。

四种事务的隔离级别:

READ UNCOMMITTED (未提交读)

  事务中的修改,即使没提交,对其他事务也是可见的。

  事务可以读取未提交的数据,也叫脏读,一般很少使用

READ COMITTED (提交读)

  一个事务开始时,只能看见已经提交的修改,并且所做的修改对其他事务不可见。

  这个级别有时候也叫不可重复读,因为两次执行同样的查询,可能会得到不同的结果。

  事务A前后执行两次查询,前一次读取某条记录之后,事务B对其进行了修改并提交,这时当A再次读取该数据的时候就会发现与之前读取的结果不一样。

  是大多数数据库默认的隔离级别(但MySQL不是)。

REPEATABLE READ (可重复读)

  保证了同一个事务多次读取同样记录的结果是一致的。但无法解决幻读。

  幻读:事务A读取某个范围内的记录时,事务B又在该范围内插入新的记录,当事务A再次读取时,会产生幻行。

  另一种幻读情况:事务A对数据库所有行做了修改时,事务B对向数据库中插入了一行新的数据。这时A发现还有没有修改的记录,就像发生幻觉一样。

  InnoDB存储引擎使用一种被称成next-key locking的策略来避免幻读(phantom)现象。

  这是MySQL (InnoDB引擎)的默认事务隔离级别。

SERIALIZABLE (可串行化)

  强制事务串行执行,在读取每行数据上都加锁,可能产生大量的超时和锁争用问题。

  只有在非常需要确保数据的一致性,且可以接受没有并发的情况下才考虑使用该级别。

死锁:

  死锁指的是多个事务在同一资源上相互占用,并请求对方占用的资源,导致恶性循环的现象。

  数据库系统中实现了各种死锁检测和死锁超时机制。

  InnoDB目前处理死锁的方法是:将持有最少行级排他锁的事务回滚。

事务日志:

  存储引擎修改表数据的时候只修改其在内存中的拷贝,再讲修改记录持久化到硬盘上的事务日志中。

  不用每次修改都将数据持久化到硬盘,能提高事务的效率。

  也被称为预写式日志,修改数据需要写两次硬盘。

  系统崩溃,重启后能根据日志恢复这部分修改的数据。

MySQL中的事务:

  MySQL提供了两种事务型存储引擎,InnoDB和NDB Cluster。

  在MySQL中默认是自动提交事务的,每个查询操作被当作一个事务。

  可以使用set autocommit来设置是否自动提交。

  可以通过set session transaction isolation level来设置隔离级别。

  在同一事务中使用多种存储引擎是不可靠的

隐式锁定:

  InnoDB采用的是两阶段锁协议。

  在事务执行过程中随时可能执行锁定,只有在提交和回滚的时候才会释放。

显示锁定:

  InnoDB支持通过特定语句显示锁定

1.4 多版本并发控制(MVCC)

  MVCC相当于行级锁的一个变种,但在很多情况下避免了加锁操作,开销更低。

  大多数都实现了非阻塞读操作,写操作也只用锁定必要的行。

  MVCC只在读提交和可重复读这两个隔离级别下工作。

原文地址:https://www.cnblogs.com/ft-greate/p/12355155.html

时间: 2024-10-02 18:24:47

MYSQL学习(二)的相关文章

MySQL学习(二)——SQL语句创建删除修改以及中文乱码问题

一.对数据库的操作 1.创建一个库 create database 库名; 创建带有编码的:create database 库名 character set 编码; 查看编码:show create database 库名; 2.删除一个库 drop database 库名; 3.使用库 use 库名; 4.查看当前正在操作的库 select database(); 二.对数据库表的操作 1.创建一张表 create table 表名( 字段名 类型(长度) [约束], 字段名 类型(长度) [

MySql学习(二) —— where / having / group by / order by / limit 简单查询

这篇博客主要记录sql的五种子句查询语法! 一个重要的概念:将字段当做变量看,无论是条件,还是函数,或者查出来的字段. select五种子句 where 条件查询 group by 分组 having 筛选 order by 排序 limit 限制结果条数 为了练习上面5种子句,先建立一张goods表,主要用于查询操作,表结构如下: 1.基础查询 —— where where常用运算符: 1.1 查出主键为20的商品 :mysql> SELECT goods_id,cat_id,goods_sn

MySQL学习(二)——MySQL多表

分页操作:使用limit(参数1,参数2) 起始位置(参数1)=(第几页-1)*每页显示的条数(参数2) 1.分类表 create table category( cid varchar(32) primary key, cname varchar(100) ); 2.商品表 create table product( pid varchar(32) primary key, pname varchar(40), price double, category_id varchar(32) );

MYSQL学习二 关于左连接

工作中有如下的SQL, 针对A.ID ='abcdefg', left  join  B和C两个表,来查找其他信息.就算是B和C中没有任何满足条件的记录,最后结果也肯定不是空.因为A.ID ='abcdefg'是存在的. SELECT ****** FROM tableA A LEFT JOIN tableB B on b.DELETED = '0' AND A.DELETED = '0' AND B.fid=A.ID LEFT JOIN tableC C ON B.XXXid=C.id AND

我的MYSQL学习心得(十二)

原文:我的MYSQL学习心得(十二) 我的MYSQL学习心得(十二) 我的MYSQL学习心得(一) 我的MYSQL学习心得(二) 我的MYSQL学习心得(三) 我的MYSQL学习心得(四) 我的MYSQL学习心得(五) 我的MYSQL学习心得(六) 我的MYSQL学习心得(七) 我的MYSQL学习心得(八) 我的MYSQL学习心得(九) 我的MYSQL学习心得(十) 我的MYSQL学习心得(十一) 这一篇<我的MYSQL学习心得(二)>将会讲解MYSQL的触发器 触发器是一个特殊的存储过程,不

mysql学习之二:mysql基本用法

安装完mysql后我们可以进行sql语句的操作: 我们可以使用以下命令连接到MySQL服务: mysql -h localhost -u root -p -h参数指定要连接的MySQL服务器地址 -u参数指定连接所使用的用户 -p参数指定使用密码验证登陆 MySQL服务绝大多数功能使用SQL语言进行管理. SQL语言一般约定俗成使用大写,但是语言本身不限制大小写.几乎所有SQL语句都必须以";"结尾. 列出所有数据库: SHOW DATABASES; 创建一个数据库(linuxcast

MySQL命令学习(二)

(13)where字句操作符 =            等于 <>          不等于 !=           不等于 <            小于 >            大于 >=          大于等于 BETWEEN          在指定的两个值之间 例如: 找出学号是0007到0009之间的学生记录(不包括0009)? SELECT* FROM student_info WHERE stu_id BETWEEN 1001101620007 AND

我的MYSQL学习心得(二)

原文:我的MYSQL学习心得(二) 我的MYSQL学习心得(二) 我的MYSQL学习心得(一) 我的MYSQL学习心得(三) 我的MYSQL学习心得(四) 我的MYSQL学习心得(五) 我的MYSQL学习心得(六) 显示宽度 MYSQL中的整数型数据类型都可以指定显示宽度,而SQLSERVER不行 创建一个表 CREATE TABLE tb_emp( id BIGINT(1)) id字段的数据类型为BIGINT(1),注意到后面的数字1,这表示的是该数据类型指定的显示宽度,指定能够显示的数值中数

Mysql学习笔记(二)数据类型 补充

原文:Mysql学习笔记(二)数据类型 补充 PS:简单的补充一下数据类型里的String类型以及列类型... 学习内容: 1.String类型 2.列类型存储需求 String类型: i.char与varchar char与varchar的类型相似,但是他们的保存方式和检索方式不同... char的存储结构是固定长度的存储...即指定了几个字节,那么就占用几个字节,如char(4),那么无论存入的是什么字串,那么都占用四个字节...char的 可表示长度范围为0-255的任何值,当保存的字节不