事务的基本操作
为了演示,需要将mysql的默认隔离级别设置成未提交:(设置为全局读已提交)
set global transaction isolation level READ UNCOMMITTED;transaction isolation level:设置事务隔离级别
事务隔离级别具体请看另一篇文章:mysql事务
四种隔离级别:
- READ UNCOMMITTED 读未提交(脏读、不可重复读、幻读都可能)
- READ COMMITTED 读已提交(Oracle 默认)
- REPEATABLE READ 可重复读(MySQL 默认)
- SERIALIZABLE 串行化(最高、最慢)
查看隔离级别的方式:(mysql版本>=8.0的命令)
当前会话隔离级别:
select @@transaction_isolation;全局隔离级别:
SELECT @@global.transaction_isolation;
与此同时我们还需要记住一个重要的命令:
show processlist;它是 MySQL 查看当前连接、线程、事务、SQL 执行状态的核心命令,非常重要!!!
事务的设置流程
通过命令启动事务:
//方法一 start transaction; //方法二 begin;设置保存点:
保存点的作用:在事务执行过程中打一个 "标记",后续可以回滚到这个标记位置,而不是回滚整个事务。
savepoint 保存点名;回滚:
作用:撤销保存点之后执行的所有操作,恢复到设置保存点时的状态。
//回滚至保存点 rollback to 保存点名; //回滚至事务开启前 rollback;提交:
commit;
需要注意的是:事务不一定需要 begin/start transaction 启动。只要关闭自动提交(SET AUTOCOMMIT=0),执行的 SQL 会自动进入事务模式,最后通过 commit 提交、rollback 回滚即可。
前面使用 begin/start transaction 启动事务,只是为了更规范、更清晰地标记事务范围,将多条 SQL 打包成一个逻辑整体,便于阅读与维护。
图片展示:
事务的启动与存档点设置:
回滚至存档点:
在数据库中,事务的本质是原子性 :一组 SQL 操作要么全部执行成功并永久生效,要么全部不执行、数据回到最初状态,绝对不会出现 "执行一半、留一半" 的情况。
事务中的操作并不会自动保存,必须通过 COMMIT 提交才会永久生效;如果未执行提交(如异常、断开连接、手动 ROLLBACK),数据库会视为事务未完成,自动回滚所有操作,恢复到事务开始前的状态。
事务的提交设置
自动提交与手动提交
通过上面"事务中的操作并不会自动保存"可以引出自动提交与手动提交概念。
自动提交设置
//自动提交 //禁止自动提交 SET AUTOCOMMIT=0; //启动自动提交 SET AUTOCOMMIT=1; //手动提交(在事务编写好后通过commit进行提交,具体方式请看后面) commit;如何看是否开启自动提交:(ON为开,OFF为关)
show variables like 'autocommit';需要注意的是:在事务执行过程中,如果出现异常、断开连接或手动终止,所有尚未提交的操作都会自动回滚,数据不会真正写入数据库 。这是数据库事务原子性的本质保证。
而自动提交与手动提交的意义,并非为了防止异常导致数据丢失 ,而是用于控制事务的范围 :决定 SQL 语句是单独执行、单独生效 ,还是多条 SQL 捆绑成一个整体事务,统一提交或回滚。
具体谈谈自动提交和手动提交
从事务的概念可以知道,事务由一组 SQL 指令构成。数据库事务的原子性保证:++事务只有全部执行成功才会真正写入数据库,一旦执行失败,则数据自动回滚到事务开始前的状态。++
手动提交是在执行完一系列 SQL 后,通过 COMMIT 手动确认提交,事务中的所有操作才会真正写入磁盘并永久保存。在此之前,所有修改仅在当前事务中可见。
自动提交则相当于把事务粒度拆到最细:每一条 SQL 执行完毕后,数据库都会自动执行 commit ,每条语句独立成为一个事务。
因此,手动提交与自动提交的核心区别在于事务的范围:手动提交将多条 SQL 打包为一个整体事务,保证原子性与一致性;而自动提交下,单条 SQL 就是一个独立事务。
当然,在开启自动提交后也能进入手动提交模式,如上面提到的《事务设置流程》里的案例就是,在运行begin;或start transaction;命令后,会短暂进入手动提交模式,之后进行的操作如果出现异常就回滚,或者设置好事务后通过commit提交并退出这个模式。


