mysql并发基础知识点总结
2022-10-23 20:28 没有波澜的天空 阅读(49) 评论(0) 编辑 收藏 举报1、并发中可能存在的问题
(1)读读 不会有问题
(2)读写 有脏读、不可重复读、幻读的问题
(3)写写 有写丢失的问题
2、事务的4个特性
ACID 原子性、一致性、隔离性、持久性
在innordb中
原子性由undolog保证
一致性由undolog+redolog保证
隔离性由事务隔离级别保证
持久性由redolog保证
3、innordb解决问题的方案
(1)写写问题
串行化或显式加锁解决。
(2)读写问题
脏读问题、不可重复读问题,由mvcc解决。
幻读问题,由串行化或者显式加间隙锁解决。
4、标准的事务的隔离级别
(1)读未提交(RU):存在脏读、不可重复读、幻读、写丢失的全部问题
(2)读已提交(RC):解决脏读,有不可重复读、幻读、写丢失的问题
(3)可重复读(RR):解决脏读、不可重复读的问题、有幻读、写丢失的问题
(4)串行化(Serializable):问题全部解决
5、innordb的事务的隔离级别(和标准的事务隔离级别有一定差异)
(1)读未提交(RU):存在脏读、不可重复读、幻读、写丢失的全部问题
(2)读已提交(RC):解决脏读,有不可重复读、幻读、写丢失的问题
(3)可重复读(RR):解决脏读、不可重复读、部分幻读的问题,有部分幻读、写丢失的问题
(4)串行化(Serializable):问题全部解决
备注:
如果一个事务中,只有快照读,RR隔离级别是没有幻读问题的。
如果一个事务中,既有快照读,又有当前读,RR隔离级别是有幻读问题的。
6、innordb锁
(1)、从加锁的范围上,分为:行锁(记录锁)、表锁、范围锁(包括间隙锁、临键锁、插入意向锁)
(2)、从加锁的排斥上,分为:共享锁(S锁)、排他锁(X锁)、意向共享锁(IS锁,只能作用于表)、意向排他锁(IX锁,只能作用于表)、自增锁(只能作用于表)
(3)、乐观锁和悲观锁,mysql中涉及的锁都是悲观锁,不提供乐观锁。但很多人误认为mvcc是乐观锁,其实这是一种无锁实现
7、innordb默认锁和显式加锁
(1)select 默认不加任何锁
如果显式加共享锁:
select .... lock in share mode
select .... for update
(2) DML语句(update、delete、insert)默认加行级排他锁
(3) DDL语句(alert、drop、create)默认加表级排他锁
8、mvcc中的当前读和快照读
(1)快照读:读取的是记录的快照中的版本。
(2)当前读:读取的是记录的最新版本,并且返回的数据记录会加上锁,保证其他事务不能并发的修改数据记录。
select默认是快照读。加上for update等是当前读。
update、delete只能是当前读
9、innordb默认事务隔离级别
可重复读。(RR)
10、innordb设置每个事务隔离级别对应的方案
(1)读未提交,系统不采取任务策略
(2)读已提交和可重复读,系统采用mvcc
(3)串行化,顺序执行
10、innordb幻读问题的彻底解决
(1)设置为串行化隔离级别(系统设置层面解决),代价太大,一般不采用
(2)间隙锁解决(手动解决,编写sql语句时解决)
实例:
在查询的一个区间内用for update
select * from user where user_id > 100 for update;
11、mvcc原理
隐藏字段、undolog、readview
12、undolog、redolog、binlog
undolog、redolog事innordb的内容,binlog是mysql底层的内容
undolog是mvvc实现的机制之一,是为了解决并发的问题
redolog是write ahead机制,为了解决事务在突然中断时数据丢失的问题
13、mysql事务提交的方式
Mysql有两种事务提交方式:
(1)自动提交(默认)
MySQL 在自动提交模式下,每个 SQL 语句都是一个独立的事务。这意味着,
当您执行一个用于更新(修改)表的语句之后,MySQL立刻把更新存储到磁盘中(除非使用BEGIN 或 START TRANSACTION显式开启事务)。
(2)手动提交
手动设置set @@autocommit = 0,即设定为非自动提交模式,只对当前的mysql命令行窗口有效,打开一个新的窗口后, 默认还是自动提交。 使用 MySQL 客户端执行 SQL 命令后必须使用commit命令执行事务,否则所执行的 SQL 命令无效, 如果想撤销事务则使用 rollback 命令(在commit之前)。
查看 MySQL 客户端的事务提交方式命令:(默认值=1,自动提交)
select @@autocommit;
修改 MySQL 客户端的事务提交方式为手动提交命令:
set @@autocommit = 0;