任务描述
本关任务:
- 修改存储过程,使得存储过程中若有错误的
SQL
则不执行,否则将事务提交; - 使用事务往
t_emp
表中插入数据。
相关知识
为了完成本关任务,你需要掌握:
-
什么是事务;
-
事务的开启与提交;
-
事务回滚。
什么是事务
可以把一系列要执行的操作称为事务,而事务管理就是管理这些操作要么完全执行,要么完全不执行。
经典的事务举例:A
要给B
转钱,首先A
的钱减少了,但是突然的数据库断电了,导致无法给B
加钱,然后由于丢失数据,B
不承认收到A
的钱;在这里事务就是确保加钱和减钱两个都完全执行或完全不执行,如果加钱失败,那么不会发生减钱。
-
事务管理的意义:保证数据操作的完整性;
-
事务的特性;
-
原子性:事务的整个操作是一个整体,不可以分割,要么全部成功,要么全部失败;
-
一致性:事务操作的前后,数据表中的数据没有变化(按示例中解释为
A
转钱给B
的前后两个人钱的总金额不会改变); -
隔离性:事务操作是相互隔离不受影响的;
-
持久性:数据一旦提交,不可改变,永久的改变数据表数据。
-
事务的开启与提交
在 MySQL
命令行的默认下,事务采用自动提交(autocommit=1
)模式。意味着,当你执行一个修改sql
语句,MySQL
会立刻更新存储到磁盘中。也就是会立马执行commit
操作。
因此开启一个手动事务必须使用begin
,start transaction
或者set autocommit=0
:
begin;
#或者
start TRANSACTION;
#或者
set autocommit=0;
commit
表示提交事务,即提交事务的所有操作。具体地说,就是将事务中所有对数据库的更新写回到磁盘上的物理数据库中,事务正常结束。
提交事务也有对应的三种方式:
commit;
#或者
commit TRANSACTION;
#或者
commit WORK;
提交事务,意味着将事务开始以来所执行的所有数据修改成为数据库的永久部分,因此也标志着一个事务的结束。一旦执行了该命令,将不能回滚事务。只有在所有修改都准备好提交给数据库时,才执行这一操作。
下面使用两个连接举例说明:
回滚事务
rollback
表示事务回滚,即在事务运行的过程中发生了某种故障,事务不能继续执行,系统将事务中对数据库的所有已完成的操作(对数据库的更新操作)全部撤销,回滚到事务开始时的状态,同时,系统将释放由事务控制的资源。因此,这条语句也标志着事务的结束。
示例:
编程要求
在右侧编辑器补充代码,完成下列两个任务:
-
在
query1.sql
中修改存储过程,使得存储过程中若有错误的SQL
则不执行,否则将事务提交。要完成此任务,你需要知道如何自定义异常:declare err int default 0; #定义一个err变量并初始值为0
declare continue handler for sqlexception set err =1; #当有sql异常的时候,sql继续往下执行,并将变量err的值改变为1
有了变量的值接收是否有异常
SQL
,就能方便我们使用判断事务是否提交了,关于更多的自定义异常学习可以学习完本关后自行搜索资料学习。 -
在
query2.sql
向t_emp
表中插入相应数据,注意平台已经为你开启事务:
id | name | deptId | salary |
---|---|---|---|
1 | Nancy | 301 | 2300 |
2 | Tod | 303 | 5600 |
3 | Carly | 301 | 3200 |
测试说明
平台会对你编写的代码进行测试:
预期输出:
+----+-------+--------+--------+
| id | name | deptId | salary |
+----+-------+--------+--------+
| 1 | Nancy | 301 | 2300 |
| 2 | Tod | 303 | 5600 |
| 3 | Carly | 301 | 3200 |
+----+-------+--------+--------+
开始你的任务吧,祝你成功!
USE mydb;
#请在此处添加实现代码
########## Begin ##########
# 修改存储过程 ———— 向 t_emp 表中插入数据(注意请勿修改提供的代码框架)
drop procedure if exists mydb.proc_insert;
delimiter $$
create procedure proc_insert()
Begin
#开启事务
start transaction ;
insert into t_emp values(1,'Nancy',301,2300);
insert into t_emp values(2,'Tod',303,5600);
insert into t_emp values(3,'Carly',301,3200);
#事务提交
commit;
END $$
delimiter ;
########## End ##########