MySql学习笔记08——事务介绍

本文详细解释了事务的基本概念,涉及事务的完整业务逻辑、InnoDB存储引擎如何记录事务日志、提交和回滚事务的操作、以及事务的四个特性(原子性、一致性、隔离性和持久性),并展示了不同隔离级别的验证过程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

事务

基本概念

事务是一个完整的业务逻辑,是一个最小的工作单元,不可再分。

一个完整的业务逻辑包括一系列的操作,这些操作是整个业务逻辑中的最小单元,这些操作要么同时成功,要么同时失败。

由于只有DML语句中才会有事务的概念,因此事务只和insert update delete语句有关。

说到底,说到本质上,一个事务其实就是多条DML语句同时成功,或者同时失败!

事务是怎么做到多条DML语句同时成功和同时失败的呢?

InnoDB存储引擎:提供一组用来记录事务性活动的日志文件

	事务开启了:
	insert
	insert
	insert
	delete
	update
	update
	update
	事务结束了!

在事务的执行过程中,每一条DML的操作都会记录到“事务性活动的日志文件”中。在事务的执行过程中,我们可以提交事务,也可以回滚事务。

提交事务&回滚事务

  • 提交事务

    ​ 清空事务性活动的日志文件,将数据全部彻底持久化到数据库表中。
    ​ 提交事务标志着,事务的结束。并且是一种全部成功的结束。

  • 回滚事务

​ 将之前所有的DML操作全部撤销,并且清空事务性活动的日志文件
​ 回滚事务标志着,事务的结束。并且是一种全部失败的结束。

​ 提交事务:commit; 语句
​ 回滚事务:rollback; 语句(回滚永远都是只能回滚到上一次的提交点!)

在MySQL中,默认的事务行为是自动提交的,每次命令成功之后就会进行一次自动提交。

通过执行命令start transaction关闭系统的自动提交。

回滚事务演示:

mysql> select * from t_student;
+----+-----------+------+
| no | name      | cno  |
+----+-----------+------+
|  1 | jack      |  100 |
|  2 | lucy      |  100 |
|  3 | lilei     |  100 |
|  4 | hanmeimei |  100 |
|  5 | zhangsan  |  101 |
|  6 | lisi      |  101 |
|  7 | wangwu    |  101 |
|  8 | zhaoliu   |  101 |
+----+-----------+------+
8 rows in set (0.00 sec)

mysql> start transaction;
Query OK, 0 rows affected (0.01 sec)

mysql> insert into t_student values(9,'ame',100);
Query OK, 1 row affected (0.01 sec)

mysql> insert into t_student values(10,'ame',100);
Query OK, 1 row affected (0.00 sec)

mysql> insert into t_student values(11,'ame',100);
Query OK, 1 row affected (0.00 sec)

mysql> select * from t_student;
+----+-----------+------+
| no | name      | cno  |
+----+-----------+------+
|  1 | jack      |  100 |
|  2 | lucy      |  100 |
|  3 | lilei     |  100 |
|  4 | hanmeimei |  100 |
|  5 | zhangsan  |  101 |
|  6 | lisi      |  101 |
|  7 | wangwu    |  101 |
|  8 | zhaoliu   |  101 |
|  9 | ame       |  100 |
| 10 | ame       |  100 |
| 11 | ame       |  100 |
+----+-----------+------+
11 rows in set (0.00 sec)

mysql> rollback;
Query OK, 0 rows affected (0.01 sec)

mysql> select * from t_student;
+----+-----------+------+
| no | name      | cno  |
+----+-----------+------+
|  1 | jack      |  100 |
|  2 | lucy      |  100 |
|  3 | lilei     |  100 |
|  4 | hanmeimei |  100 |
|  5 | zhangsan  |  101 |
|  6 | lisi      |  101 |
|  7 | wangwu    |  101 |
|  8 | zhaoliu   |  101 |
+----+-----------+------+
8 rows in set (0.00 sec)

提交事务演示:

mysql> create table t_student(
    -> no int primary key auto_increment,
    -> name varchar(32)
    -> );
Query OK, 0 rows affected (0.03 sec)

mysql> select * from t_student;
Empty set (0.00 sec)

mysql> start transaction;
Query OK, 0 rows affected (0.00 sec)

mysql> insert into t_student values(1,'jack');
Query OK, 1 row affected (0.00 sec)

mysql> insert into t_student(name) values('nick');
Query OK, 1 row affected (0.00 sec)

mysql> insert into t_student(name) values('nick');
Query OK, 1 row affected (0.00 sec)

mysql> insert into t_student(name) values('nick');
Query OK, 1 row affected (0.00 sec)

mysql> insert into t_student(name) values('nick');
Query OK, 1 row affected (0.00 sec)

mysql> insert into t_student(name) values('nick');
Query OK, 1 row affected (0.00 sec)

mysql> commit;
Query OK, 0 rows affected (0.01 sec)

mysql> select * from t_student;
+----+------+
| no | name |
+----+------+
|  1 | jack |
|  2 | nick |
|  3 | nick |
|  4 | nick |
|  5 | nick |
|  6 | nick |
+----+------+
6 rows in set (0.00 sec)

mysql> rollback;
Query OK, 0 rows affected (0.00 sec)

mysql> select * from t_student;
+----+------+
| no | name |
+----+------+
|  1 | jack |
|  2 | nick |
|  3 | nick |
|  4 | nick |
|  5 | nick |
|  6 | nick |
+----+------+
6 rows in set (0.00 sec)

commit操作实际上是将数据持久化的操作,在进行这个操作之前,仍在事务进行当作,数据仍然可以进行回滚,但是数据持久化之后就不能进行回滚了。

事务的四个特性

  • A : 原子性

    事务是最小的工作单元,不可再分。

  • C: 一致性

​ 所有事务要求,在同一个事务当中,所有操作必须同时成功,或者同时失败,保证数据的一致性。

  • I: 隔离性

    不同的事务之间具有隔离,当两个事务想要操作同一张表的时候,他们之间的墙就会产生一定的隔离作用

  • D: 持久性

    事务开始的标志一般是start transaction, 事务最终结束的标志是进行commit操作,对数据进行了持久化,相当于将数据写进硬盘里。

事务的隔离性

事务和事务之间的隔离性具有四个不同的隔离级别:

  • 读未提交 read uncommitted
    • 事务A可以读取到事务B未提交的数据。
    • 但是这种隔离级别会出现脏读现象,我们称读到脏数据
  • 读已提交 read committed
    • 事务A只能读取到事务B已经提交的数据。
    • 不可重复读取数据:在事务开启之后,第一次读到的数据是3条,当前事务还没有结束,可能第二次再读取的时候,读到的数据是4条,3不等于4,称为不可重复读取。
  • 可重复读 repeatable read (mysql默认的隔离级别)
    • 两个事务对同一张表进行操作,不管对方是怎样操作的,各自只能看到自己事务中所做出的操作,即使事务B提交了,事务A也无法读取事务B修改后的数据。
  • 序列化 serializable(最高的隔离级别)
    • 效率最低,安全级别最高
    • 这种隔离级别表现为事务排队,不能并发,事务A还在操作表1,事务B如果想要对表1进行操作,需要等事务A结束。

验证各种事务隔离级别

查看隔离级别:

查看系统隔离级别:select @@global.tx_isolation;
查看会话隔离级别(5.0以上版本)select @@tx_isolation;
查看会话隔离级别(8.0以上版本)select @@transaction_isolation;
mysql> select @@transaction_isolation;
+-------------------------+
| @@transaction_isolation |
+-------------------------+
| REPEATABLE-READ         |  # mysql默认的隔离级别
+-------------------------+

设置隔离级别:

mysql> set global transaction isolation level read uncommitted;
mysql> set global transaction isolation level read committed;
mysql> set global transaction isolation level repeatable read;
mysql> set global transaction isolation level serializable;

设置完后记得重新登陆一下mysql

  • read uncommitted验证

image-20220718140606285

右边事务进行insert后,左边事务是看的见的

  • read committed验证

image-20220718141117168

  • repeatable read验证

image-20220718142107958

右侧事务修改完之后,左侧事务也看不见修改。

  • serializable验证

image-20220718143721244

右边事务在等左边事务commit,才会执行。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值