一:事务的ACID特性及为什么要使用事务 :
1.事务的ACID特性: 事务的ACID特性指的是 Atomicity (原子性), Consistency (一致性), Isolation (隔离 性)和 Durability (持久性)。 原子性:支持事务的数据库中最基本的特性,一组SQL语句要么全部成功,要么全部失败,不会出现只执行了⼀半的情况,如果事务在执行过程中发生错误,会回滚( Rollback )到事务开始前的状态 ,就像这个事务从来没有执行过⼀样; 一致性:事务执行完成后,保证数据正确并且符合预期 隔离 性:多个事务之间不能相互影响 持久性:事务一但提交就要保存到存储介质中(磁盘),不论数据库是否损坏,都不会丢失数据 总结:原子性,隔离性,持久性,共同作用实现一致性
2.为什么要使用事务: 事务具备的ACID特性,是我们使用事务的原因,在我们日常的业务场景中有⼤量的需求要⽤事务来保证。支持事务的数据库能够简化我们的编程模型, 不需要我们去考虑各种各样的潜在错误和并发问题,在使⽤事务过程中,要么提交,要么回滚,不⽤去考虑⽹络异常,服务器宕机等其他因素,因此我们经常接触的事务本质上是数据库对 ACID 模型的⼀个实现,是为应用层服务的。 因此在使用数据库过程中,对于修改只要提交成功,数据就可以安全的保存,只要回滚就可以回到,保存点事务之初
二:如何使用事务:
1.查看支持事务的存储引擎:在MySQL中支持事务的存储引擎是InnoDB,可以通过
show engines;
2.语法:
开始⼀个新的事务:start transaction 或者 begin;
提交当前事务,并对更改持久化保存:commit;
回滚当前事务,取消其更改:rollback;
例子1:开启事务,执行修改后回滚
1.开启,并把张三和李四的balance字段分别加100和减100
回滚:数据回到初始状态。
例子2:开启一个事务,执行修改后提: 再查询发现数据已被修改,说明数据已经持久化到磁盘
3.设置保存点:
语法:SAVEPOINT 保持点名字;
例子:张三李四分别修改了两次,设置了两个保存点,然后插入了一条数据
修改后:
回滚第二个保存点:
回滚到第一个保存点:
回滚时不指定保存点,直接回滚到事务开始时的原始状态,事务关闭:
4.提交事务:
默认情况下,MySQL是自动提交事务的,也就是说我们执行的每个修改操作,比如插入、更新和删除,都会自动开启一个事务并在语句执行完成之后自动提交,发生异常时自动回滚。
查看当前事务是否⾃动提交可以使用:
代码语言:javascript复制show variables like 'autocommit';
通过以下语句设置事务为自动或手动提交:
代码语言:javascript复制# 设置事务⾃动提交
mysql> SET AUTOCOMMIT=1; # ⽅式⼀
mysql> SET AUTOCOMMIT=ON; # ⽅式⼆
# 设置事务⼿动提交
mysql> SET AUTOCOMMIT=0; # ⽅式⼀
mysql> SET AUTOCOMMIT=OFF; # ⽅式⼆
注意:
只要使⽤ START TRANSACTION 或 BEGIN 开启事务,必须要通过 COMMIT 提交才会持久 化,与是否设置 SET autocommit ⽆关。(总结:开启事务落盘必须提交)
三:事务的隔离级别:
1.什么是隔离级性:
MySQL服务可以同时被多个客户端访问,每个客户端执行的DML语句以事务为基本单位,那么不同的客户端在对同⼀张表中的同⼀条数据进行修改的时候就可能出现相互影响的情况,为了保证不同的事务之间在执行的过程中不受影响,那么事务之间就需要要相互隔离,这种特性就是隔离性。
2.隔离级别:
事务间不同程度的隔离,称为事务的隔离级别;不同的隔离级别在性能和安全方面做了取舍,有的隔离级别注重并发性,有的注重安全性,有的则是并发和安全适中;在MySQL的InnoDB引擎中事务的隔离级别有四种:
(1). READ UNCOMMITTED ,读未提交
(2). READ COMMITTED ,读已提交
(3). REPEATABLE READ ,可重复读(默认)
(4). SERIALIZABLE ,串行化
注意:从上到下安全性逐渐升高,从下到上性能性逐渐升高
(1). READ UNCOMMITTED ,读未提交 解释:
对应事务中,事务A对事务进行修改,但是事务B访问了事务A未提交的数据,这个情况叫做 脏读 , 事务B读到的是事务A回滚的数据
例子:
(2). READ COMMITTED ,读已提交 解释 :
事务A第一次查询了某条记录,事务B进行了修改并且提交,事务A再次查询这条记录发现与第一次 查询结果不一致 ,这种现象叫做 不可重复读 (多次读取到的结果不一致)
例子:
(3). REPEATABLE READ ,可重复读(默认):
事务A第一次查询到的结果集,第二次以相同方式查询到的结果集,与第一次的 结果集不一致 ,这种现象叫做 幻读
注意:Mysql Innodb引擎使用了间隙锁(next-key)锁住了目标行和之前的信息,解决了部分幻读问题
(MySQL中的间隙锁(Gap Lock)是一种针对InnoDB存储引擎的锁定机制,用于锁定一个范围,但不包括记录本身,主要用于防止幻读。 间隙锁只在可重复读(REPEATABLE READ)事务隔离级别下工作。 )
例子:
(4). SERIALIZABLE ,串行化 :解决了所有数据安全问题,所有事务都是一个挨一个执行,一个事务必须等到上一个事务执行完成才可以执行,解决了所有并发安全问题。
3.查看和设置隔离级别:
这里注意Mysql事务隔离级别默认是,可重复读( REPEATABLE READ ) ;
两个@@是表示查看系统变量。
3.1.查看:
代码语言:javascript复制# 全局作⽤域
SELECT @@GLOBAL.transaction_isolation;
# 会话作⽤域
SELECT @@SESSION.transaction_isolation;
# 可以看到默认的事务隔离级别是REPEATABLE-READ(可重复读)
3.2.设置: