存储过程

简介

存储程序是被存储在服务器中的组合SQL语句,经编译创建并保存在数据库中,用户可通过存储过程的名字调用执行。存储过程核心思想就是数据库SQL语言层面的封装与重用性。使用存储过程可以较少应用系统的业务复杂性,但是会增加数据库服务器系统的负荷。

基本语法

1
2
CREATE PROCEDURE sp_name ([proc_parameter[,...]])
[characteristic ...] routine_body

案例

1
2
3
4
5
6
7
8
-- 查询学生表中性别为男的学生总数
CREATE PROCEDURE u_pro(IN v_sex VARCHAR(5) CHARACTER SET utf8 ,OUT num INT)
BEGIN
SELECT COUNT(*) INTO num FROM student WHERE v_sex=sex;
end

CALL u_pro('男',@num);
SELECT @num;
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
-- 计算1+到n的值
CREATE PROCEDURE addresult(IN n INT)
BEGIN
DECLARE i INT;
DECLARE sum INT;
SET sum =0;
SET i =1;

WHILE i<n DO
SET sum=sum+i;
SET i=i+1;
END WHILE;

SELECT sum ;
END

call addresult(50);
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
-- 计算1+到n的值
CREATE PROCEDURE addresult2(in n INT,out sum INT)
BEGIN
DECLARE i INT;
DECLARE sum INT;
SET sum =0;
SET i =1;

WHILE i<n DO
SET sum=sum+i;
SET i=i+1;
END WHILE;

SELECT sum ;
END

call addresult2(50,@sum);
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
-- 判断变量
CREATE PROCEDURE user_main_pro3(INOUT v_id INT)
BEGIN
# 定义变量
DECLARE v_count INT(11);
# 判断
IF v_id > 3 THEN
SET v_count = 100;
ELSE
SET v_count = 500;
END IF;
# 返回赋值
SET v_id = v_count;
END

SET @v_id=1;
call user_main_pro3(@v_id);
SELECT @v_id;

事务处理

注意点

MySQL中Innodb支持事务,而MyISAM不支持事务

事务的特性

  1. 原子性(Atomicity):事务开始后的所有操作,要么全部做完,要么全部不做。事务执行过程中出错,会回滚到事务开始前的状态,所有的操作就像没有发生一样。
  2. 一致性(Consistency):事务开始前和结束后,数据库的完整性约束没有被破坏 。比如A向B转账,不可能A扣了钱,B却没收到。
  3. 隔离性(Isolation):同一时间,只允许一个事务请求同一数据,不同的事务之间彼此没有任何干扰。比如A正在从一张银行卡中取钱,在A取钱的过程结束前,B不能向这张卡转账。
  4. 持久性(Durability):事务完成后,事务对数据库的所有更新将被保存到数据库,不能回滚。

并发问题

  1. 脏读:事务A读取了事务B更新的数据,然后B回滚操作,那么A读取到的数据是脏数据
  2. 不可重复读:事务 A 多次读取同一数据,事务 B 在事务A多次读取的过程中,对数据作了更新并提交,导致事务A多次读取同一数据时,结果 不一致。
  3. 幻读:系统管理员A将数据库中所有学生的成绩从具体分数改为ABCDE等级,但是系统管理员B就在这个时候插入了一条具体分数的记录,当系统管理员A改结束后发现还有一条记录没有改过来,就好像发生了幻觉一样,这时就叫幻读。

注:不可重复读的和幻读很容易混淆,不可重复读侧重于修改,幻读侧重于新增或删除。
解决不可重复读的问题只需锁住满足条件的行,解决幻读需要锁表

事务隔离级别

事务隔离级别脏读不可重复读幻读
读未提交(read-uncommitted)
不可重复读(read-committed)
可重复读(repeatable-read)
串行化(serializable)

设置隔离级别:

1
SET SESSION TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;

只有增删改语句才支持事务