数据库-事务/隔离

1 MySQL基础

1.1 关系型数据库

关系型数据库: 建立在关系模型上的数据库
表明了数据库中所存储的数据之间的联系(一对一,一对多,多对多)

数据被存储在各种表中,每张表的每一行存放一条数据

大部分关系型数据库都使用SQL语句来操作数据库中的数据
且大部分数据库都支持事务的四大特性ACID

1.2 MySQL介绍

MySQL: 一种关系型数据库,主要用于持久化存储系统中一些数据,如用户信息
是开源且免费较为成熟的数据库,默认端口号为3306

2 存储引擎

2.1 MySQL中的存储引擎

可以使用show engines;来查看MySQL提供的所有存储引擎
在这里插入图片描述

可以看到MySQL默认使用的是InnoDB,且只有InnoDB引擎支持事务

2.2 MyISAM和InnoDB的区别

在MySQL5.5之前,MyISAM是默认的存储引擎,虽然MyISAM性能和特性尚可,但是MyISAM不支持行级锁和事务,且最大的缺陷是崩溃后无法恢复,在MySQL5.5之后,MySQL引入了InnoDB

MyISAM和InnoDB的区别:

1,是否支持行级锁
MyISAM只有表级锁
InnoDB支持行级锁和表级锁,默认为行级锁

即MyISAM一锁就是一张表,在并发的情况下性能很糟糕
而InnoDB的行级锁在并发时,有更好的性能

2,是否支持事务
MyISAM不支持事务
InnoDB提供事务支持,具有提交和回滚事务的能力

3,是否支持外键
MyISAM不支持外键
InnoDB支持外键

一般不建议在数据库层面使用外键,在应用层可以解决	

4,是否支持数据库崩溃后的安全恢复
MyISAM不支持
InnoDB支持,使用InnoDB的数据库在异常崩溃后
数据库重新启动时会保证数据库恢复到崩溃前的状态,这个过程依赖于redo log(重做日志)

InnoDB通过使用redo log保证事务的持久性,使用undo log来保证事务的原子性
InnoDB引擎通过使用锁机制,MVCC等手段保证事务的隔离性
保证了事务的持久性,原子性,隔离性之后,一致性才能得到保障

5,是否支持MVCC
MVCC可以看作是行级锁的一个升级,可以有效减少加锁操作,提升性能
MyISAM不支持
InnoDB支持

3 锁机制和InnoDB锁算法

MyISAM使用表级锁
InnoDB支持行级锁和表级锁,默认使用行级锁

表级锁和行级锁对比:

表级锁: MySQL中粒度最大的锁,对当前整张表进行加锁,实现简单,资源消耗较少
加锁快,不会出现死锁,并发度最低

行级锁: MySQL中粒度最小的锁,只对当前操作的行加锁,行级锁能大大减少操作数据库的冲突
并发度高,单锁的开销也最大,加锁慢,可能会出现死锁

InnoDB锁的算法:

1Record Lock: 记录锁,单个行上的锁

2Gap Lock: 间隙锁,锁定一个范围,不包括行本身

3Next-key Lock: 临键锁,锁定一个范围,包括行本身

4 查询缓存

执行查询语句时,会先查询缓存,不过这个功能在MySQL8.0之后被移除,因为不太常用
也可以通过配置来开启MySQL的缓存

当缓存开启后,在同样查询环境以及数据下,会直接在缓存中返回结果
缓存虽然能够提升数据库的查询性能,但是也带来了额外的开销
每次查询完后,都要进行一次缓存操作,失效后还要销毁

5 事务

5.1 事务概念

事务就是逻辑上的一组操作,要么都执行,要么都不执行

示例:

AB转账2000元时,这个转账操作涉及两个关键操作
1,将A的余额扣除2000
2,将B的余额增加2000

事务会把这两个操作看作一个整体,这个整体内的操作要么都成功,要么都失败

5.2 数据库事务

数据库事务可以保证多个对数据库的操作(也就是SQL语句)构成一个逻辑上的整体
构成这个逻辑上的整体的这些数据库操作遵循: 要么全部执行成功,要么全部不执行

# 开启一个事务
START TRANSACTION;
# 多条 SQL 语句
SQL1,SQL2...
## 提交事务
COMMIT;

在这里插入图片描述

5.3 事务的ACID特性

1,原子性(Atomicity): 事务是最小的执行单位,不允许分割
事务的原子性确保动作要么全部完成,要么全部失败

2,一致性(Consistency): 执行事务前后,数据保持一致
如转账业务中,无论事务是否成功,收款人和打款人总额不变

3,隔离性(Isolation): 并发访问数据库时,一个用户的事务不会被其它事务干扰
各并发事务之间的数据是独立的

4,持久性(Durabilily): 一个事务被提交后,它对数据库中数据的改变是持久的
即使数据库发生了故障,也不会对其有影响

事务ACID的实现原理:

MySQLInnoDB:
通过redo log重做日志来保证事务的持久性
使用undo log回滚日志保证事务的原子性
使用锁机制,MVCC等手段保证事务的隔离性

当保证了事务的原子性,持久性,隔离性后,一致性才能得到保障

5.4 并发事务带来的问题

在应用程序中,多个事务可能并发运行,经常会操作相同的数据来完成各自的任务(多个用户对同一数据进行操作),并发虽然是必须的,但可能导致以下问题:

1,脏读: 当一个事务A正在访问数据并对数据进行了修改,而这种修改还没有提交到数据库中
这时另一个事务B也访问了这个数据,然后使用了这个数据
那么事务B读到的数据就是"脏数据",依据"脏数据"所做的操作可能是不正确的

2,丢失修改: 指在一个事务A读取一个数据时,另一个事务B也访问了该数据
那么在第一个事务A中修改了该数据后,第二个事务B也修改了该数据
这样第一个事务A内修改的结果就会被丢失

3,不可重读: 指在一个事务A内可能多次读取同一数据,在这个事务没有结束时
另一个事务B也访问了该数据,那么在第一个事务A中的两次读取之间
由于第二个事务B的修改导致第一个事务A两次读取同一个数据,但得到了不同的值
这样发生在一个事务A内两次读取的数据不一样的情况,称为不可重读性

4,幻读: 幻读与不可重读类似,当一个事务A读取了几行数据后
另一个事务B插入了一些数据,在A随后的读取中,发现多了一些"原本不存在的记录"
像幻觉一样,称为幻读

5.5 事务隔离级别

SQL标准定义了4个隔离级别:

READ-UNCOMMITTED 读取未提交
最低的隔离级别,允许读取尚未提交的数据变更
可能会导致脏读,幻读,不可重复读

READ-COMMITTED 读取已提交
允许读取并发事务已经提交的数据
可以阻止脏读,但是幻读和不可重复读仍有可能发生

REPEATABLE-READ 可重复读
对同一记录多次读取结果都是一致的,除非数据被本事务自己修改
可以阻止脏读和不可重复读,但幻读仍有可能发生

SERIALIZABLE 可串行化
最高的隔离级别,完全服从ACID,所有事物依次执行,事物之间无法干扰

在这里插入图片描述

5.6 MySQL默认隔离级别

InnoDB默认支持的隔离级别是REPEATABLE-READ(可重复读)

隔离级别越低,事物请求的锁越少
大部分数据库系统的隔离级别都是READ-COMMITTED(读取提交内容)
但InnoDB默认使用的REPEATABLE-READ(可重复读) 不会有性能损失
InnoDB在分布式事物的情况下一般用到 SERIALIZABLE(可串行化) 隔离级别

6 MVCC 多版本并发控制

6.1 MVCC介绍

MVCC在MySQLInnoDB中的实现主要是为了提高数据库并发性能
用更好的方式去处理读-写冲突,即使有读写冲突,也能做到不加锁,非阻塞并发读

6.1.1 当前读和快照读

当前读:
读取的是记录的最新版本,读取的同时还要保证其它并发事务不能修改当前记录
会对读取的记录进行加锁

快照读:
即不加锁的非阻塞读,基于MVCC
MVCC可以看作行级锁的一个变种,在很多情况下,避免了加锁操作降低了开销
快照读即读取到的并不一定是数据的最新版本,可能是之前的版本

MVCC就是为了实现读-写冲突不加锁,这个读是"快照读"

6.2 MVCC好处

MVCC是一种用来解决读写冲突的无锁并发控制
也就是为事务分配单向增长的时间戳,为每个修改保存一个版本 版本与事务时间戳关联
读操作只读该事务开始前的数据库快照,所以MVCC可以解决:

1,在并发读写记录时,不用加锁,提高了并发性能

2,还可以解决脏读,幻读,不可重复读,但不能解决更新丢失的问题

6.3 MVCC原理

MVCC依赖于记录中的3个隐式字段,undo日志,ReadView来实现的

13个隐式字段
DB_TRX_ID: 最近修改该记录的事务ID
DB_ROLL_PTR: 回滚指针,指向这条记录的上一个版本
DB_ROW_ID: 隐藏的自增主键

2,undo日志
undo日志主要分为两种
insert undo log: 代表事务insert新记录时产生的undo log 
只在事务回滚时需要 并在事务被提交后可以被丢弃

update undo log: 事务在进行update或delete时产生的undo log 
不仅在事务回滚时需要,在快照读时也需要 不能随便删除

3ReadView 读视图
ReadView就是事务进行快照读操作产生的读视图,在该事务执行的快照读的那一刻
会生成数据库系统当前的一个快照,记录并维护系统当前活跃事务的ID

当某个事务执行快照读时,对该记录创建一个ReadView,把它比作条件用来判断当前事务能看到哪个版本的数据
既可能是当前最新的数据,也可能是该行记录的undo log里某个版本的数据

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值