一、介绍
事务由单独单元的一个或多个 SQL 语句组成。在这个单元中,每个 MySQL 语句是相互依赖的。而整个单独单元作为一个不可分割的整体,如果单元中某条 SQL 语句执行失败,整个单元都将回滚。所有受到影响的数据都会返回到事务开始以前的状态。如果单元中的所有 SQL 语句均执行成功,则事务被顺利执行。
简单来说事务可以让一个或一组 sql 语句组成一个执行单元,这个执行单元要么全部执行,要么全部不执行。
二、事务的 ACID 属性
1)原子性(Atomicity)
原子性是指事务是一个不可分割的工作单位,事务中的操作要么都发生,要么都不发生。
2)一致性(Consistency)
事务必须使数据库从一个一致性状态变换到另外一个一致性的状态。
3)隔离性(Isolation)
事务的隔离性是指一个事务的执行不能被其他事务干扰,即一个事务内部的操作及使用的数据对并发的其他事务是隔离的,并发执行的各个事务之间不能互相干扰。
4)持久性(Durability)
持久性是指一个事务一旦被提交,它对数据库中数据的改变就是永久性的,就下来的其他操作和数据库故障不应该对其有任何的影响。
三、存储引擎
存储引擎是指在数据库中的数据的存储方式,在 MySQL 中常用的存储引擎有:innodb,myisam,memmory 等。其中 innodb 支持事务,而 myisam,memmory 等不支持事务。不同的数据库默认的存储引擎是不一样的,MySQL 的默认存储引擎是 innodb。
查看数据库存储引擎的命令(存储引擎后面详讲)。
show engines;
四、事务的执行
1、隐式事务:
事务没有明显的开启和结束的标记,比如没有关闭 MySQL 的自动提交事务,直接执行 insert、update、delete 语句。
2、显式事务:
事务具有明确的开启和结束的标记。
3、事务的执行步骤:
1)开启事务
start transaction;
也可以关闭 MySQL 的自动提交事务。
set autocommit=0;
查看 MySQL 是否自动提交事务。
show variables like 'autocommit';
2)执行 SQL 语句
执行 SQL 语句,如:select、insert、update、delete。
3)结束事务
提交事务。
commit;
回滚事务。
rollback;
五、事务的并发
对于同时运行的多个事务,当这些事务访问数据库中相同的数据时,如果没有采用必要的隔离机制,就会导致各种并发问题。
1、事务并发导致的问题:
1)脏读
对于两个事务 A 和 B,A 读取了已经 B 更新但没有提交的数据之后,若 B 回滚,A 读取的内容就是无效的。
2)不可重复读
对于两个事务 A 和 B,A 读取了一个记录,然后 B 更新了该记录,之后 A 再读取该记录,值就不同了。
3)幻读
对于两个事务 A 和 B,A 读取了一个表,然后 B 在该表中插入了一些新记录,之后如果 A 再次读取该表,就会多出来几行。
2、数据库事务的隔离级别
一个事务与其他事务隔离的程度称为隔离级别,数据库规定了多种事务隔离级别,不同隔离级别对应不同的干扰程度,隔离级别越高,数据的一致性就越好,并发性越弱,效率也就越低。拦截程度:读未提交 < 读已提交 < 重复读 < 可串行化。
1)Read Uncommitted(读未提交)
一个事务可以读到另一个事务还未提交的数据,这就引发了脏读。读取到的是数据库内存中的数据,而并非是真正磁盘上的数据。
2)Read Committed(读已提交)
和上一个相反,一个事务只能读到其他事务已提交的数据,没有提交的数据读不出来,这样造成前后读取的结果不一样。
3)Repeatable Read(重复读)
可以让事务在自己的会话中重复读取数据,并且不会出现结果不一样的状况,即使其他事务已经提交了,也依然还显示以前的数据。
4)Serializable(可串行化)
如果有一个连接的隔离级别设置了可串行化,那么谁先打开事务,谁就有了执行的权利,其他事务只能等前面的事务提交或者回滚才能执行。
5)不同隔离级别的事务并发问题
隔离级别 | 脏读 | 不可重复读 | 幻读 |
---|---|---|---|
Read Uncommitted | √ | √ | √ |
Read Committed | × | √ | √ |
Repeatable Read | × | × | √ |
Serializable | × | × | × |
3、隔离级别的设置
MySQL 支持 4 种隔离级别,默认隔离级别为 Repeatable Read。
1)查看隔离级别
MySQL8 以后的版本命令改成了 transaction_isolation,以前是 tx_isolation。
查看当前会话的事务隔离级别。
select @@transaction_isolation;
-- 以前版本 select @@tx_isolation;
查看当前系统的事务隔离级别。
select @@global.transaction_isolation;
-- 以前版本 select @@global.tx_isolation;
2)修改隔离级别
修改当前会话的事务隔离级别。
set session transaction isolation level 隔离级别;
修改当前系统的事务隔离级别。
set global transaction isolation level 隔离级别;
4、savepoint 节点
使用 savepoint 关键字可以给事务设置一个保存点,回滚事务的时候可以回滚到指定保存点。
语法:
savepoint 节点名;
例子:
1)开启事务
start transaction;
2)执行SQL语句
delete from zyx where id=1;
3)设置保存点
savepoint zyx1;
4)执行SQL语句
delete from zyx where id=2;
5)回滚到保存点
rollback to zyx1;
6)提交或回滚
commit;-- 提交
rollback;-- 回滚
最后提交事务后,查找数据库会发现第一个SQL语句执行了,第二个SQL语句回滚了。
标题:MySQL中的事务
作者:Yi-Xing
地址:http://47.94.239.232/articles/2019/10/12/1570844512437.html
博客中若有不恰当的地方,请您一定要告诉我。前路崎岖,望我们可以互相帮助,并肩前行!