开发者学堂课程【MySQL 实操课程:MySQL 下事务的开启、提交、回滚语句应用】学习笔记,与课程紧密联系,让用户快速学习知识。
课程地址:https://developer.aliyun.com/learning/course/717/detail/12814
MySQL 下事务的开启、提交、回滚语句应用
目录:
一、事务应用前期准备工作
二、演示实例
三、事务应用
四、事务回滚
五、事务之隐式提交
六、事务之隐式回滚
一、事务应用前期准备工作
1、查看自动提交缺省设置 (MySQL 默认是开启自动提交的)。
2、创建一个用来进行事务测试的表。
3、插入3条测试数据。
show variables like
‘
autocommit';
create table user(id int,name varchar(20);
insert into user values(1,zhangsan",(2"lisi'),(3,wangwu');
select * from user;
二、演示实例
1、MySQL 默认开启自动提交
(1)连接 RDS 数据库。
选择通过 Cloud Shell 阿里云页面演示。连接 IP:ssh root@47.112.159.55 ,输入密码后回车。连接RDS:[root@i Zwz9bize6nk8hug8j0vywZ ~]# /usr/local/mysql/bin/mysql -hrm-wz9c2e2q42u426f3z.mysql.rds.aliyuncs.com -uroot -p
回车,显示已经成功连接。
(2)使用创建好的 aliyun 测试数据库
mysql> show databases; // 打开数据库列表;回车看到数据库列表。
mysql> use aliyun;
//使用 aliyun 数据库
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A
Database changed
mysql> select * from emp;
//选择 aliyun 数据库中叫 emp 的表
//看到表中有四条数据。
//查看当前自动提交模式
mysql> show variables
l
ike‘
%autocommit%'
;
// 注意 autocommit 中间没有下划线,是连起的。回车,看到默认设置为 ON。
(3)当执行某一条 select,会自动成功的执行。
mysql> update emp set ename=‘zhaoliu’ where id=4;
^c^c -- query aborted
//能自动阻塞
ERROR 1317 (70100): Query execution was inter rupted
mysql> insert into emp (ename hiredate, sal, deptno) values ( ' zhaoliu', 2020-07-18 ,7500,1);
//插入一条数据
Query OK,1 row affected (0.00 sec)
//数据已经写入进去
mysql> select * from emp;
//查询是否成功写入
//看到数据已写入
(4)通过另一个客户端访问 aliyun 数据库查询插入的数据是否成功
mysql> use aliyun ;
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A
Database changed
mysql> select * from emp;
通过另一个客户端查询看到已经成功写入。
(5)关闭自动执行。把 autocomit 设置为0。
mysql> set autocommit=0;
Query OK, 0 rows affected (0.00 sec)
mysql> show variables like‘%autocommit%’;
//查询自动提交变量
结果显示自动执行提交已经关闭。
(6)再插入一条数据
mysql> insert into emp (ename,hiredate,sal,deptno) values (‘andy', 2020-05-18 ,12000,2);
Query OK,1 row affected (0.00 sec)
mysql> select * from emp;
//查询数据是否插入成功
可以看到,新增 andy 的数据已经插入到第一个 cloudshell 里了。
(7)在第二个 cloudshell 里查看 andy 的数据是否成功写入
mysql> select * from emp;
看到第二个 cloudshell 里并没有写入 andy 的数据。这是因为在第一个 cloudshell里 autocomit 设置为0,已经关闭的默认自动提交。需要手动提交。在第一个cloudshell 里设置:
mysql> commit; //手动设置提交
Query OK, 0 rows affected (0.00 sec)
再到第二个 cloudshell 里查询 select * from emp; 就能查询到 andy 的数据。
2、创建事务测试表
(1)打开自动提交。在第一个 cloudshell 里设置
mysql> set autocormit=1; //设置 autocormit 为1,打开自动提交
Query OK,0 rows affected (0.00 sec)
mysql> show variables like ‘%autocommit% ' ;
自动提交已经打开。在第二个 cloudshell 里也已经打开自动提交
(2)创建测试表。在第一个 cloudshell 里编辑:
mysql> create table user (id int, name varchar (20)) ;
Query OK,0 rows affected (0.02 sec)
mysql> insert into user values (1, 'zhangsan'), (2, 'lisi'), (3, 'wangwu');
Query OK, 3 rows affected (0.00 sec)
Records: 3 Duplicates: 0 Warnings: 0
mysql> select * from user;
确定已经成功插入新增数据。在第二个 cloudshell 里也成功插入。
(3)可以显示的去关闭自动提交。也可以用 begin 的方式关闭自动提交。在第一个 cloudshell 里编辑:
mysql> begin;
Query OK, 0 rows affected (0.00 sec)
mysql> insert into user values (4, 'zhaoliu') :
Query OK,1 row affected (0.00 sec)
mysql> select * from user ;
发现成功插入新增数据。在第二个 cloudshell 里查询却没有插入新增数据zhaoliu。
通过 begin 也会隐式的去开启事务。可以把自动提交手动关闭,另外也可以通过begin 的方式。
(4)回滚
mysql> rollbake;
Query OK, 0 rows affected (0.00 sec)
rollbake 把当前 begin 开启后所有写入的操作回滚到事务开启之前的状态。
(5)开启之前是三条数据,查询
mysql> select * from user ;
看到有变回开始前的三条数据
注意:当执行 rollbake 操作或者 commit 操作时,代表该事务已经结束。
(6)start transaction 和 begin 是等同作用。在第一个 cloudshell 里编辑:
mysql> start transaction;
Query OK, 0 rows affected (0.00 sec)
mysql> insert into user values (4, 'zhaoliu') ;
Query OK,1 row affected (0.00 sec)
mysql> select * from user ;
看到成功插入新数据,共四条数据。
再将其回滚:
mysql> rollbake;
Query OK, 0 rows affected (0.00 sec)
mysql> select * from user ;
查询后又只有三条数据,回到 start transaction 之前的状态。
rollbake 为回滚。要开启新的事务可以通过 begin 或者 start transaction 这两种隐式提交。
(7)注意:begin 或者 start transaction 这两种隐式提交开启事务后会不会把变量 autocommit 关闭了?
mysql> begin;
Query OK,0 rows affected (0.00 sec)
mysql> show variables like‘%tautocommitt%’;
可以看到变量的值并没有改为 false。
mysql> rol1back;
Query OK, 0 rows affected (0.00 sec)
三、事务应用
1、分别打开两个 MySQL 客户端 session1 和 session2。
2、session1 开启事务,并插入一条数据,session1 可看到该数据。
#sesssion1
begin;
insert into user values(4,'zhaoliu');
select * from user;
3、Session2 无法看到刚才 session1 插入的数据4 zhaoliu。因 session1 还未手动提交。
#session2
select * from user;
4、session1 客户端提交当前事务。
#sesssion1
commit;
//手动执行提交写入操作
5、session2 可以看到刚 session1 插入的数据。因 session1 已提交。
#session2
select * from user;
6、因 MySQL 默认的事务隔离级别是课重复读,故该场景下能看到。
注意:这种情况并不是在所有场景下效果等同。跟事务的隔离级别有关系。
如果把事务的隔离级别改为未提交。那么在 session1 里能看到未提交的数据,在session2 里则不能。
四、事务回滚
当关闭 MySQL 的自动提交后,或者开启一个事务后,数据库的开发人员是可以根据需要进行回滚。回滚一般叫撤销,撤销事务开启后的操作。
1、开启事务。
2、插入一条数据。
3、回滚。
4、查询,发现刚插入的数据被回滚了。
begin;
insert into user values(5,'sunqi');
select * from user;
rollback;
select * from user;
五、事务之隐式提交
1、当事务提交前执行了 DDL 语句的操作或再次输入 begin 或 start transaction 命令时,会触发隐式提交。
2、演示示例
在第一个 cloudshell 里编辑:
mysql> begin;
Query OK, 0 rows affected (0.00 sec)
mysql> select * from user;
看到三条数据。
mysql> insert into user values (4, 'zhaoliu') ;
Query OK, 1 row affected (0.00 sec)
mysql> select * from user ;
看到四条数据,新增了 zhaoliu。这时,在第二个 cloudshell 里查询不到新增数据zhaoliu。
在第一个 cloudshell 里再次 begin,
mysql> begin; //再次开启 begin
Query OK, 0 rows affected (0.00 sec)
在第二个 cloudshell 里查询有新增数据 zhaoliu。
在第二次执行 begin 的时候,会把第一次 begin 开启的事务操作进行提交。
也可以多次 rollback。
3、隐式提交语句
(1)直接使用 begin 或 start transaction 命令
(2)使用DDL 语句。如:创建数据库、创建表、创建索引、删除数据库、删除索引、创建存储过程、账号授权等。只要执行 DDL 语句,也会触发隐式提交。
六、事务之隐式回滚
1、当前事务提交前退出当前会话、连接操作或者关机情况下,会触发隐式回滚。
2、当执行 exit 退出 mysql 客户端后,重新进入查询,发现刚插入的数据并未成功插入
3、演示示例
在第一个 cloudshell 里编辑:
mysql> begin;
Query OK, 0 rows affected (0.00 sec)
mysql> insert into user values (5, 'sunqi');
Query OK,1 row affected (0.00 sec)
在第二个 cloudshell 里查询不到新增数据 sunqi。
在第一个 cloudshell 里执行退出:
mysql> exit
// 退出
Bye
[root@iZwz9bize6nk8hug8j0vywZ ~]#/usr/1ocal/mysq1/bin/ mysql -hrm-wz9c2e2q42u426f3z ,mysql . rds . aliyuncs .com -uroot -P
Enter password:
……
再到第二个 cloudshell 里查询仍旧没有新增数据 sunqi。
没有手动提交,数据 sunqi 则没有写入进去。