MySQL事物(详解并发问题和隔离级别)(小白也能懂哦)

1.事物的概念
2.事物的四大特性(ACID)
3.事物的创建
4.事物的并发问题和解决
5.回滚点
6.事物的适用模式

1.事物的概念

事物由单独单元的一个或者多个SQL语句组成,在这个单元中,每个SQL语句是相互依赖的,而整个单独单元作为一个不可分割的整体,如果单元中某条SQL语句一旦执行失败或产生错误,整个单元将会回滚,所有受到影响的数据将返回到事物开始以前的状态,如果单元中的所有SQL语句均执行成功,则事物将会顺利执行

用事物举个例子:

假如小明要给小红转账1000元,这个转账会涉及到两个关键操作就是:将小明的余额减少1000元,将小红的余额增加1000元。万一在这两个操作之间突然出现错误比如银行系统崩溃,导致小明余额减少而小红的余额没有增加,这样就不对了。事务就是保证这两个关键操作要么都成功,要么都要失败。

2.事物的四大特性(ACID)

在这里插入图片描述
用一些比较规范的语言解释:

1.原子性: 事务是最小的执行单位,不允许分割。事务的原子性确保动作要么全部完成,要么完全不起作用;
2.一致性: 执行事务前后,数据保持一致,多个事务对同一个数据读取的结果是相同的;
3.隔离性: 并发访问数据库时,一个用户的事务不被其他事务所干扰,各并发事务之间数据库是独立的;
4.持久性: 一个事务被提交之后。它对数据库中数据的改变是持久的,即使数据库发生故障也不应该对其有任何影响。

用大白话解释:

1.原子性(A):一个事物不可分割,要么都执行要么都不执行
2.一致性(C ):一个事物执行会使数据从一个状态切换到另一个状态
3.隔离性(I):一个事物的执行不会受另一个事物的干扰
4.持久性(D):一个事物一旦提交则会永久改变数据库的数据

3.事物的创建

3.1关于事物的提交方式

MySQL数据库中事物默认自动提交

什么意思呢,就是一条DML(增删改)语句会自动提交一次事物(事物里边的内容只能包含增删查改),我们在对表中的数据进行增删改等操作的时候,表中的数据会做出相应的永久性更改,也就是说我们想要永久更改表中的数据就必须提交事物,增删改是默认的自动提交,所以我们每次运行我们的SQL语句就会永久性更改

我们可以查看事物的默认提交:
语句:

select @@autocommit

在这里插入图片描述
可以看到默认值是1,也就是默认自动提交

我们修改默认自动提交为默认手动提交
语句:

set @@autocommit=0

3.2事物的手动提交步骤

手动提交的三个操作

1.开启事物:start transaction(可写也可不写)
2.回滚:rollback:回到事物开启前的状态
3.提交:commit:运行SQL语句并且永久更改SQL语句里边的内容

我们拿一个student表来说:
在这里插入图片描述

注意:

想要手动提交事物必须先更改事物的默认提交方式

我们举一个例子,我们修改所有同学的性别都为男,再修改所有同学的年龄都为20
语句:

set @@autocommit=0;
start transaction(可写也可不写)
update student set ssex=“男”
update student set age=20
commit(或者rollback);

当我们使用rollback的时候就会回滚,不会对表中的数据进行更改,相当于时光倒流到开启事物的那一步,但是我们提交后就会永久性更改

4.事物的并发问题和解决

4.1事物的并发问题

对于同时运行的多个事物访问数据库中相同的元素,如果没有采取必要的隔离机制就会导致并发问题

并发问题分为以下三个:

1.脏读:对于两个事物a,b,a读取了已经被b更新单但还没有提交的字段,之后若b回滚,那么a读取的内容就是临时的无效的不正确的
2.不可重复读:对于两个事物a,b,a读取一个字段然后b更新了该字段之后a再读取同一字段值就不同了
3.幻读:对于事物a,b,a从一个表中读取一个字段,然后b在表里插入一些新的行,a再读的时候就会多出来几行

我们举一个脏读的例子,其他的两种就不再演示了

首先我们有一个表为student
在这里插入图片描述
我们先把隔离级别调最低(因为此时才会发生脏读)为READ-UNCOMMITTED,然后我们用事物把翠花的性别改成男,但是不提交事物
在这里插入图片描述

再打开另一个cmd命令行,然后查询(当然这个cmd窗口的隔离级别也要设置成READ-UNCOMMITTED):
在这里插入图片描述
我们会发现翠花的性别已经更改,但是如果此时我们在第一个cmd命令行输入回滚,那么第二个命令行此时查看的翠花的性别是临时的,不是正确的
在这里插入图片描述
我们再用第二个命令行查看就会发现其实翠花的性别和第一次查询有所不同,所以第一次我我们读到的数据是脏数据,也就是脏读
在这里插入图片描述

4.2事物并发问题的解决:

我们可以设置隔离级别来避免并发问题的出现
隔离级别的种类(由低到高依次介绍):

1.READ-UNCOMMITTED(读取未提交): 最低的隔离级别,允许读取尚未提交的数据变更,可能会导致脏读、幻读或不可重复读。
2.READ-COMMITTED(读取已提交): 允许读取并发事务已经提交的数据,可以阻止脏读,但是幻读或不可重复读仍有可能发生。
3.REPEATABLE-READ(可重复读): 对同一字段的多次读取结果都是一致的,除非数据是被本身事务自己所修改,可以阻止脏读和不可重复读,但幻读仍有可能发生。
4.SERIALIZABLE(可串行化): 最高的隔离级别,完全服从ACID的隔离级别。所有的事务依次逐个执行,这样事务之间就完全不可能产生干扰,也就是说,该级别可以防止脏读、不可重复读以及幻读。

各种隔离级别可以导致的并发问题:

在这里插入图片描述

对于上图也就是说×就可以避免此类型的并发问题

1.MySQL默认的隔离级别REPEATABLE_READ,可以用 select @@tx_isolation来查看
2.我们可以用set session transaction isolation level + 隔离级别来设置隔离级别

5.回滚点

关键字savepaint

例子:

set autocommit=0;
update 表 set sex=‘女’ where id =2;
savepaint a;
update 表 set sname=‘李白’ where id =3;
rollback to a;
这里的a是回滚点名字,这里从后往前回滚所以update 表 set sex=‘女’ where id =2;这条指令就不会恢复,到回滚点就会停下。这里还要注意回滚点只能和rollback连用

还有一个注意点:delete和truncate在事物使用使用时的区别

在事物中delete在事物回滚时可以恢复删除的内容,但是truncate在回滚后不会恢复

6.事物的适用模式

了解存储引擎

在MySQL中的数据用各种不同的技术存储在文件或者内存中,在MySQL中用的最多的存储引擎有innodb,myisam,memory等,其中innodb支持事物,myisam,memory不支持事物

通过下面这个命令查看数据库支持的存储引擎

show engines

猜你喜欢

转载自blog.csdn.net/qq_45737068/article/details/106169580