事务,关系型数据事务4大特性,事务的隔离级别,MVCC,锁机制

事务

事务就是一次完整的数据库操作,这个操作过程中可能包含多条SQL的执行,这多条SQL的执行是一个整体,要么都执行成功,要么都执行失败

举例:转账操作:从A账号向B账号转钱, A账号+100时 ,B账号必须-100

网上下单支付:下订单到卖家,支付到平台

MySQL中只有innodb引擎支持数据库事务

事务用来管理 insert,update,delete 语句。

关系型数据事务4大特性

一般来说,事务是必须满足 4 个条件(ACID):原子性(Atomicity,或称不可分割性)、一致性(Consistency)、隔离性(Isolation,又称独立性)、持久 性(Durability)。

原子性:一次事务过程中的多个操作,要么都成功,要么都失败

持久性:事务一旦提交,数据就不可以改变,即使数据库服务出现问题

隔离性:数据库允许同时有多个事务进行访问,这时就需要对事务间的操作进行隔离

​ 隔离可分为4个级别:

​ 读未提交 问题:脏读

扫描二维码关注公众号,回复: 16774772 查看本文章

​ 读已提交 解决 脏读 问题:不可重复读

​ 可重复读 解决 不可重复读 问题:幻读

​ 串行化 解决一切问题 类似于加锁,效率低

一致性:在事务开始之前和事务结束以后,数据库的完整性没有被破坏。

例如:多种方式对银行账户余额进行多次同时操作,最终余额应该是我们所预期的结果,不能出现错误

-- 设置MySQL事务的提交方式为手动提交
SET GLOBAL autocommit=0;

-- 查看事务提交模式
SHOW GLOBAL VARIABLES LIKE 'autocommit';

BEGIN;
	INSERT INTO test(NAME)VALUES("aaaaa");
	
	ROLLBACK;
	
	SELECT * FROM test;
	
	
	
BEGIN;
	INSERT INTO test(NAME)VALUES("aaaaa");
	
	SELECT * FROM test;
	
	COMMIT;
	
	SELECT * FROM test;

1.读脏数据:读到了垃圾数据 A事务读到了B事务未提交的数据

2.不可重复读 A事务开启后,读取了两次数据,结果两次数据不一样(预期的效果是A在同一个事务中读取的数据是一样的)

3.幻读:A事务开启后读取到的两次数据数量不一致

事务的隔离级别

读 未提交:A可以读到B未提交的数据 问题:会有脏读 几乎不用

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-JOMstxoy-1642776968173)(C:\Users\云\AppData\Roaming\Typora\typora-user-images\1642774124588.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-t5Pzm5o7-1642776968174)(C:\Users\云\AppData\Roaming\Typora\typora-user-images\1642774140500.png)]

读 已提交:A不能读到B未提交的数据,只能读到B已提交的数据 解决了脏读问题 同时会发生不可重复读的问题

eg:解决脏读问题

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ZcR7ZzbU-1642776968174)(C:\Users\云\AppData\Roaming\Typora\typora-user-images\1642774956763.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-6pyb3aER-1642776968175)(C:\Users\云\AppData\Roaming\Typora\typora-user-images\1642774980614.png)]

eg:带来了不可重复读的问题

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-oqbYIrZ0-1642776968175)(C:\Users\云\AppData\Roaming\Typora\typora-user-images\1642775516505.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-9c4qhGdy-1642776968176)(C:\Users\云\AppData\Roaming\Typora\typora-user-images\1642775537567.png)]

可重复读:A事务开启后,第一次读到某个数据后,那么在这个数据中,第二次在查询同样的数据时,和原来是一致的,重复读.解决了不可重复读

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-raeeFFGB-1642776968177)(C:\Users\云\AppData\Roaming\Typora\typora-user-images\1642775967566.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-OZe1b4Zh-1642776968178)(C:\Users\云\AppData\Roaming\Typora\typora-user-images\1642775983544.png)]

将事务提交后,重新查询,即可查询到最新的数据

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-gj0EToSW-1642776968179)(C:\Users\云\AppData\Roaming\Typora\typora-user-images\1642776095714.png)]

eg:在mysql8.0中对应Innodb引擎中不会产生幻读
在这里插入图片描述
在这里插入图片描述

串行化:解决所有问题,一次值允许一个事务进行操作,是最安全的,也是效率最低的

MVCC

MVCC(多版本并发控制 Multi-Version Concurrent Control)

为了提升mysql读-写,写-读两个操作可以同时进行,写-写,mysql支持行级锁的,如果操作同一行数据,那么肯定是不可以的

每次对表中的记录操作时,会保存一个日志(undolog)里面会记录事务的id号.

如果有多个事务操作时,他们会根据事务id,找到自己操作的版本记录

不同的隔离级别在读数据时会根据版本链生成一个ReadView(临时读视图) 版本链快照

READ COMMITTED:每次读取数据前都生成一个 ReadView 产生不可重复读 其中数据发生改变,版本链中也会发生修改,每次读的时候ReadView中的数据就发生了改变,所以不可重复读

REPEATABLE READ:在第一次读取数据时生成一个 ReadView,之后数据发生改变,版本链发生变化,没有关系,第一次读的时候已经拍过照了.

锁机制

mysql中的锁主要是用于写写操作

,mysql中支持行锁,间隙锁和表锁

行锁:某个事务对某一行记录进行写操作时会把当前行锁住,其他事务不能对当前行操作

粒度最小,并发最高,频繁加锁释放锁.

间隙锁:锁的是一块区间,在条件范围操作时会给满足条件的区间数据进行加锁

表锁:当某一个事务对某一行记录操作时,可以将整个表锁住,innodb用的少,myisam支持表锁

**共享锁(S锁)**又称为读锁

**排它锁(X锁)**又称写锁

在查询是必要的情况下也可以为读操作加排他锁select * from表名 for update 语句

1.乐观锁:并不会真正的去锁某行记录,而是通过一个版本号来实现的.

没有加锁,可以通过版本号来区别

2.悲观锁:上面的行锁,间隙锁,表锁等都是悲观锁

猜你喜欢

转载自blog.csdn.net/crraxx/article/details/122630999