9047_1575431266

2020-10-15   阅读量: 610

一看就懂的MySQL事务介绍

扫码加入数据分析学习群

MySQL事务介绍

前言

一、事务的概念及特点

1.1:事务的概念

1.2:事务的ACID特性

二、事务的操作

2.1:MySQL操作事务

2.1.1:使用事务命令控制事务
2.1.2:使用set设置控制事务

前言

上回我们已经说到了MySQL索引,已经对数据库大致进行了整体的操作,那么在数据库中,我们除了普通的增删改查还能做什么呢?这边我们就需要引入一个概念——索引。

一、事务的概念及特点

1.1:事务的概念

事务是一种机制、一个操作序列,包含了一组数据库操作命令,并且把所有的命令作为一个整体一起向系统提交或者撤销操作请求,即这一组数据库命令要么都执行,要么都不执行。事务是一个不可分割的工作逻辑单元,在数据库系统上执行并发操作时,事务是最小的控制单元。事务适用于用户同时操作数据库系统的场景,如银行、保险公司及证券交易系统等,通过事务的整体性以保证数据的一致性。事务是保证了一组操作的平稳性和可预测性的技术。

1.2:事务的ACID特性

事务有四个特性:原子性(automaticity)、一致性(consistency)、隔离性(isolation)、持久性(durability)。

  • ***原子性:***事务是一个完整的操作,各元素是不可分的,即原子的。事务中的所有元素必须作为一个整体提交或者回滚。如果事务中的任何元素失败,则整个事务将失败。

  • ***一致性:***当事务完成时,数据必须处于一致状态;当事务开始之前,数据库中存储的数据处于一致状态;在正在进行的事务中,数据可能处于不一致的状态;当事务成功完成时,数据必须再次回到已知的一致状态。

  • ***隔离性:***对数据进行修改的所有并发事务是彼此隔离的,这表明事务必须是独立的,它不应以任何方式依赖于或影响其他事务。修改数据的事务可以在另一个使用相同数据的事务开始之前访问这些数据,或者在另一个使用相同数据的事务结束之后访问这些数据。

  • ***持久性:***指不管系统是否发生了故障,事务处理的结果都是永久的。一旦事务被提交,事务的效果会被永久地保留在数据库中。

二、事务的操作

2.1:MySQL操作事务

默认情况下MySQL的事务是自动提交的。之前我们用SQL操作数据库时,一条语句执行后,系统会自动执行事务提交。当需要把一组语句作为一个事务提交是,需要手动对事务进行控制。手动控制事务有2种方法,一种是使用事务处理命令控制,另一种是使用set设置事务的处理方式。

2.1.1:使用事务命令控制事务

MySQL中使用命令控制事务需要用到3个命令:

  • begin:表示开始一个事务,后面会有多条数据库操作语句执行

  • commit:表示提交一个事务,对应前面的begin操作,它们之间的数据库操作语句一起完成。

  • rollback:表示回滚一个事务,在begin和commit之间,如果某一个数据库操作语句出现错误,执行rollback回滚,数据库回到begin之前的状态,也就是操作语句都没执行。

① 下面我们开始演示操作,首先我们接着昨天数据库进行操作,假如我们在数据库中再插入两条数据,他们是提交在一个事务中

mysql> begin;mysql> insert into student values('1','张三','90');mysql> insert into student values('2','李四','91');mysql> commit;mysql> select * from student;+--------+--------+--------+| 学号   | 姓名   | 成绩   |+--------+--------+--------+|      1 | 张三   |     90 ||      2 | 李四   |     91 |+--------+--------+--------+
2 rows in set (0.00 sec)123456789101112

使用begin开始事务,然后执行两条插入语句,最后使用commit提交事务,此时两条数据插入到了数据表中,这两条数据是作为一个整体操作。

② 但是假如我们使用begin开始事务,但是却不用commit结尾会怎么样?

mysql> begin;mysql> insert into student values('1','张三','90');mysql> insert into student values('2','李四','91');mysql> select * from student;+--------+--------+--------+| 学号   | 姓名   | 成绩   |+--------+--------+--------+|      1 | 张三   |     90 ||      2 | 李四   |     91 |+--------+--------+--------+
2 rows in set (0.00 sec)1234567891011

此时我们通过查询语句可以看到表中已经插入了数据,但是我们并没有提交事务,那么我们直接退出数据库会怎么样呢?

mysql> exit;Bye
mysql -uroot -p
mysql> use class;mysql> select *from student;Empty set (0.00 sec)123456

此时表中并没有我们之前插入的数据,说明使用begin开始了事务,在执行完操作语句之后,必须使用commit进行提交,否则数据是不能自动提交的,也就是多条数据操作语句作为一个整体需要使用commit进行整体的事务提交。

③ rollback回滚的使用,假设插入一条数据后,需要恢复到插入前数据库的状态,使用rollback执行事务回滚

mysql> begin;mysql> insert into student values('1','张三','90');mysql> select * from student;+--------+--------+--------+| 学号   | 姓名   | 成绩   |+--------+--------+--------+|      1 | 张三   |     90 |+--------+--------+--------+
1 row in set (0.00 sec)mysql> rollback;mysql> select * from student;Empty set (0.00 sec12345678910111213

我们可以发现,使用begin开始事务,然后我们执行插入命令,查询表数据可以发现,已经插入了数据,但是假如我们执行了rollback程序之后,再查看表数据,发现先前插入的数据已经没有了,说明rollback是数据表回滚到了begin之前的状态。

④ 通过上面饿回滚命令,我们就像,我其实并不像回滚到那么前的状态,比方说 一个事务包含了多条语句,假如我们只是想回到某一条语句的状态,那么我们就需要用savepoint定义一个回滚点,通俗来说就像我们打游戏中的保存游戏一下,然后直接载入这个存档就行了。rollback决定回滚到的位置。

mysql> begin;mysql> insert into student('1','张三','90');mysql> savepoint a;mysql> insert into student values('2','李四','91');mysql> savepoint b;12345

我们执行第一条插入命令后,定义一个回滚点a,执行第二条插入命令之后,定义一个回滚点b,如果直接使用rollback语句,就会向上次前面一样,表中不会有插入数据,现在通过回滚点来进行回滚

mysql> rollback to savepoint a;
mysql> select * from student;
+--------+--------+--------+
| 学号   | 姓名   | 成绩   |
+--------+--------+--------+
|      1 | 张三   |     90 |
+--------+--------+--------+
1 row in set (0.00 sec)12345678

由此可以看出我们回滚到了第一条插入命令,但是此时我们并没有进行命令提交,所以表中并不会保存数据,假如需要保存数据,我们就是用commit命令提交。

2.1.2:使用set设置控制事务

前文中我们已经提及了MySQL是默认提交就是,意思就是在你不进行begin命令式,就是可以自动保存数据,但是我们也可以修改为不自动提交,使用set命令操作

set autocommit = 0 :禁止自动提交set antocommit = 1 :开启自动提交12

① 其实在实际情况中,MySQL启动时autocommit的值默认的是1,修改为0,则需要手动提交,也就是使用前面用到的commit命令,回滚使用rollback命令。

mysql> set autocommit = 0;mysql> insert into student values('1','张三','90');mysql> insert into student values('2','李四','91');mysql> commit;mysql> select * from student;+--------+--------+--------+| 学号   | 姓名   | 成绩   |+--------+--------+--------+|      1 | 张三   |     90 ||      2 | 李四   |     91 |+--------+--------+--------+
2 rows in set (0.00 sec)1234567891011121314

这边因为使用禁止自动提交,我们需要最后是由commit命令提交事务。

② 设置了禁止自动提交之后,假如不使用commit提交操作语句,就跟只使用begin的情况相同,执行的语句都会失效。

mysql> set autocommit = 0;mysql> insert into student values('1','张三','90');mysql> insert into student values('2','李四','91');mysql> commit;mysql> select * from student;+--------+--------+--------+| 学号   | 姓名   | 成绩   |+--------+--------+--------+|      1 | 张三   |     90 ||      2 | 李四   |     91 |+--------+--------+--------+
2 rows in set (0.00 sec)mysql> exitBye
mysql -u root -p
mysql> use class;mysql> select * from student;Empty set (0.00 sec)12345678910111213141516171819

可以发现,如果不使用commit提交事务,我们在退出MySQL数据库之后再重新进入,插入的数据是不会保存的。


51.9468 4 0 关注作者 收藏

评论(0)


暂无数据

推荐课程