找往期文章包括但不限于本期文章中不懂的知识点:
个人主页:我要学编程(ಥ_ಥ)-CSDN博客
所属专栏: MYSQL
目录
事务的概念
事务的ACID特性
使用事务
查看支持事务的存储引擎
事务的语法
保存点
自动/手动提交事务
事务的隔离性和隔离级别
事务的概念
首先,得了解什么是事务? 事务将一组SQL语句打包成一个整体,在这组SQL语句的执行过程中,要么全部成功,要么全部失败,以保证数据的一致性。
事务的ACID特性
事务的ACID特性指的是 Atomicity (原子性), Consistency (一致性), Isolation (隔离性)和 Durability (持久性)。
Atomicity(原子性):一个事务中的所有操作,要么全部成功,要么全部失败,不会出现只执
行了一半的情况,如果事务在执行过程中发生错误,会回滚(Rollback)到事务开始前的状
态,就像这个事务从来没有执行过一样;
Consistency(一致性):在事务开始之前和事务结束以后,数据库的完整性不会被破坏。这表
示写入的数据必须完全符合所有的预设规则,包括数据的精度、关联性以及关于事务执行过程中服
务器崩溃后如何恢复。简单理解就是事务开始前后的数据量要一致;
Isolation(隔离性):数据库允许多个并发事务同时对数据进行读写和修改,隔离性可以防止多
个事务并发执行时由于交叉执行而导致数据的不一致。事务可以指定不同的隔离级别,以权衡在不
同的应用场景下数据库性能和安全;
Durabi礼ity(持久性):事务处理结束后,对数据的修改将永久的写入存储介质,即便系统故障
也不会丢失。
正因为事务具备上述四个特性,保证了在使用事务过程中,要么提交,要么回滚,不用去考虑网络异常,服务器宕机等其他因素,因此事务在数据库的使用是非常频繁的。
既然事务这么好用,那么我们该怎么去使用事务呢?
使用事务
查看支持事务的存储引擎
在使用事务之前,得查看我们本机的数据库是否支持事务。
在MySQL中支持事务的存储引擎是InnoDB,可以通过 show engines; 语句查看:
知道了本机中的数据库是支持事务之后,便可以开始进行事务了。
事务的语法
-- 开始一个新的事务
start transaction;
-- 或者下面这种写法
begin;
-- 提交当前事务,并对SQL语句的执行而影响的数据进行持久化保存
commit;
-- 回滚当前事务,并取消SQL语句的执行而影响的数据
rollback;
注意:无论是commit 还是 rollback 都会把事务关闭。
下面就来进行实操:
-- 开启事务
start transaction;
-- 插入一条数据
insert into student values (NULL, '小红', 18, 0);
-- 在事务中查看student表中的结果集
select * from student;
-- 回滚事务
rollback;
-- 在回滚之后,再查看student表中的结果集
select * from student;
从上面的结果,我们就可以看出回滚之后,事务中的SQL语句全部失效。现在我们再来观察commit 的效果。
-- 开启事务
start transaction;
-- 插入一条数据
insert into student values (NULL, '小红', 18, 0);
-- 在事务中查看student表中的结果集
select * from student;
-- 提交事务
commit;
-- 在提交之后,再查看student表中的结果集
select * from student;
从上面的结果,我们可以看出提交事务之后,事务中的SQL语句便生效了。
保存点
在事务执行的过程中设置保存点,回滚时指定保存点可以把数据恢复到保存点的状态。当事务中有多个修改数据的SQL语句时(包括插入、删除、更新),便可以设置多个保存点,以保证数据的一致性和操作方便。
语法:
savepoint savepoint_name;
示例:
-- 开启事务
start transaction;
-- 修改多条数据
savepoint sp1; -- 设置第一个保存点
delete from student where id = 8 or id = 9;
select * from student;
savepoint sp2; -- 设置第二个保存点
insert into student values (NULL, '小丽', 19, 0);
select * from student;
savepoint sp3; -- 设置第三个保存点
update student set age = 20 where name = '张三';
select * from student;
-- 可以通过回滚到某一个保存点来取消修改
rollback to sp3;
select * from student;
-- 如果rollback后面啥也不跟,那就是默认回滚到事务开始之前,并关闭事务
rollback;
select * from student;
自动/手动提交事务
默认情况下,MySQL是自动提交事务的,也就是说我们执行的每个修改操作,比如插入、更新和删除,都会自动开启一个事务并在语句执行完成之后自动提交,发生异常时自动回滚。即每一条SQL语句对应着一个事务。
查看当前事务是否自动提交可以使用以下语句:
show variables like 'autocommit';
如果value对应的是off,就是关闭的意思。
可以通过以下语句设置事务为自动或手动提交:
-- 设置事务为自动提交
set autocommit = 1; -- 方式一
set autocommit = on; -- 方式二
-- 设置事务为手动提交
set autocommit = 0; -- 方式一
set autocommit = off; -- 方式二
其实就是把自动提交开启或者关闭即可。
使用事务的时候,要注意一下三点:
1、只要使用start transaction 或 begin 开启事务,必须要通过commit 提交才会持久化,与是否设置set commit 无关。因为我们手动开启事务之后,必须要自己手动关闭事务。
2、手动提交模式下,不用显示开启事务,执行修改操作后,提交或回滚事务时直接使用commit
或rollback。因为手动提交下,就是需要我们自己把事务手动提交。
3、已提交的事务是不能够回滚的。
事务的隔离性和隔离级别
隔离性的概念:
MySQL服务可以同时被多个客户端访问,每个客户端执行的SQL语句是以事务为基本单位,那么不同的客户端在对同一张表中的同一条数据进行修改的时候就可能出现相互影响的情况,为了保证不同的事务之间在执行的过程中不受影响,那么事务之间就需要要相互隔离,这种特性就是隔离性。这就类似于我们在食堂里面打饭的场景,同一个窗口,同一份饭菜,肯定有先来后到,不可能出现两个人同时拿到这份饭菜(假设不存在多个阿姨打饭的情况)。这就隔离开了。
隔离级别分类:
事务具有隔离性,那么如何实现事务之间的隔离?隔离到什么程度?如何保证数据安全的同时也
要兼顾性能?这都是要思考的问题。
事务间不同程度的隔离,称为事务的隔离级别;不同的隔离级别在性能和安全方面做了取舍,有
的隔离级别注重并发性,有的注重安全性,有的则是并发和安全适中;在MySQL的InnoDB引擎中事务的隔离级别有四种,分别是:
READ UNCOMMITTED,读未提交 —— 性能最强,但安全性最差。
READCOMMITTED,读已提交 —— 性能稍逊于读未提交,安全性比读未提交高。
REPEATABLE READ,可重复读(InnoDB默认) —— 性能比读已提交差,安全性比读已提交高。
SERIALIZABLE,串行化 —— 性能最差,但安全性最高。
下面就来解释上面四种隔离级别:
READ UNCOMMITED —— 在读取数据时,可以读取到用户正在编辑的数据。这些数据处于事务中,但是还未提交。虽然性能高,但会造成一种现象'脏读'——读取的数据不一定是真实的,可以用户后面会进行修改,再提交。
READ COMMITED —— 和上面的一对比,我们就知道这个是只能读取已经提交的数据。但这还会造成一种现象‘不可重复读’——可能现在这个时刻读取的数据内容是这样的,但是在另外一个时刻读取的数据内容确实另外的。
REPEATABLE READ —— 在出现不可重复读的基础上,进行了改进。既然这些数据在被读取时,可能刷新一下就变样了,那直接把这些数据加上枷锁,那么用户就不能进行修改了。但还会出现另外一个问题,此时用户往这个表中插入了数据,即结果集的条数发生了变化。这种现象叫做‘幻读’。
SERIALIZABLE —— 这个就是和我们学过的队列一样,数据是一次一次的读取。致使其不会出现安全问题,但是效率相比之下就慢很多。
好啦!本期 初始MYSQL数据库(5)—— 事务 的学习之旅就到此结束啦!我们下一期再一起学习吧!