黑马程序员技术交流社区
标题: 【济南中心】PHP课程同步笔记day19:数据库操作-事务 [打印本页]
作者: 小鲁哥哥 时间: 2017-7-8 16:21
标题: 【济南中心】PHP课程同步笔记day19:数据库操作-事务
本帖最后由 小鲁哥哥 于 2017-7-8 16:31 编辑
【济南中心】PHP课程同步笔记day19:数据库操作-事务
事务(transaction)控制什么叫做事务?设想这样一个情形:
小明,小花是一对,他们分处不同的城市,他们的银行账号都是一个银行的。
某天,小花要买一个iphone,但肾已用完,需要向小明借钱。借5000.
....不管他们在什么操作界面(柜台,atm,手机,网银,。。。),最终系统内部都会有这样两条语句的执行:
update 存款表 set 存款 = 存款-5000 where 账户 = ‘小明’;
update 存款表 set 存款 = 存款+5000 where 账户 = ‘小花’;
但,这两条语句执行的过程中,可能就会有意外:断电,地震,网线被老鼠咬断。。。
如果第一条语句执行完了,发生上述情况,则结果是:
他们分手了——他们的账户信息不对应(不一致);
事务,就是在mysql系统内部,用于保证类似这种“多步进行的事情”,能够“按一次进行”来执行的机制:
该多步的事情,要么都做了,要么都不做!
事务的特点
原子性:一个事务中的所有语句,应该做到:要么全做,要么一个都不做;
一致性:让数据保持逻辑上的“合理性”,比如:一个商品出库时,既要让商品库中的该商品数量减1,又要让对应用户的购物车中的该商品加1;
隔离性:如果多个事务同时并发执行,但每个事务就像各自独立执行一样。
持久性:一个事务执行成功,则对数据来说应该是一个明确的硬盘数据更改(而不仅仅是内存中的变化)。
怎么实现事务?
事务模式:
其实是一个设置项:
set autocommit = on,表示开启自动提交模式;——为系统的默认设置
set autocommit = off 关闭自动提交模式;——此时,执行语句后,必须使用commit才生效
应用中,更常见的是,在php中,以一个明确而典型的“开启事务”的代码模式来实现,如下所示:
mysql_query(“ start transaction”); //开启一个事务,也可以“begin”
$result1 = mysql_query(“insert .....”);
$result2 = mysql_query(“update .....”);
$result3 = mysql_query(“delete .... “)
....事务中的语句,只有增删改才受事务影响
if ( $result1 === false || $result2 === false || $result === false || ......){
mysql_query(“ rollback “); //回滚事务,不管任何其中一个失败,其他的语句全都“撤销”
echo “失败了”
}else{
mysql_query( “ commit “); //提交事务,此时,这一行语句执行成,前面那些行才算成功!
echo “执行成功”
}
说明:
1,事务机制,只对增删改这种会改变数据库的语句有效(产生控制能力);
2,使用这种开启一个新事务(start transaction)的模式,则自动提交模式是on或者off都无所谓
3,这种情况,都必须是commit执行了才算生效。
变量
有两种变量:
常规变量(普通变量):
必须先定义,后使用;
定义形式:
declare 变量名 类型 【default 默认值】;
使用:
赋值: set 变量名 = 值(表达式);
或其他场合,比如: if 变量名 > 10 then 。。。。。。
会话变量:类似php中的变量:可以直接赋值;第一次赋值就算定义;
赋值形式1:
set @变量名 = 值(表达式);
赋值形式2:
select @变量名 := 值(表达式);
赋值形式3:
select 值(表达式) into @变量名 ;
两种变量最重要的区别是:使用场合:
1,会话变量可以在“所有场合使用”;
2,普通变量只能在定义“存储过程”,“存储函数”,“触发器”的时候使用。
3,实际上,上述3个场景,也是流程控制语句所能使用的场景;
存储函数概念:
什么叫存储函数?
存储函数就是函数,只是要求:必须返回一个数据(值);
定义形式:
使用函数:
使用自己定义的存储函数,跟使用系统函数一样!!!
在任何需要一个数据的位置,都可以调用存储函数,以获得一个数据;
函数名(实参1,实参2,....)
删除存储函数:
drop function 【if exists】 函数名;
存储过程概念:
什么叫存储过程?
存储过程还是函数,只是要求:绝不能返回一个数据(值);
定义形式:
说明:
1,存储过程内部可以使用增删改查语句,
对比:存储函数内部职能使用增删改语句;
2,存储过程和存储函数内部都可以使用各种流程控制和各种变量;
3,存储过程如果内部有select语句,则存储过程执行的结果也是“结果集”(数据表)
4,修饰符:
in:表示该形参是用于接收实参数据的,这是默认值,不写就是它;
out:表示该形参是用于将函数内部执行的结果传出数据到函数外部“对应实参”的;
inout:具有上述2个作用;
其中,out和inout的形参对应的实参,必须是“变量”——因为其用于接收数据
调用存储过程:
call 存储过程名(实参1,实参2,....)
触发器含义:
是一段预先定义好的代码——其实存储函数,存储过程也是一段代码!
它是在某个表在进行某种操作(增,删,改)的时候,会被“触发”而执行该段代码!
定义形式:
create trigger 触发器名 触发时机 触发事件 on 表名 for each row
begin
......触发器内部的语句.....
跟函数类似:可以有增删改语句,但不可以有查询语句;
不可以有返回值!(即不能有return 语句)
end;
说明:
1, 触发时机:其实就是2个单词:
before after
2,触发事件:其实就是3个单词:
insert delete update
则1和2合起来表示:在增删改之前或之后,去做其中定义好的事情(执行代码);
3,在触发器定义的内部,有2个关键字可以并经常使用:
new: 代表insert语句或update语句的“新数据行”,其中可以获取任何一个字段数据的值,类似这样:
set @v1 = new.id; #获得了新的id
set @v2 = new.age; #获得了新的age值
old:代表delete语句或update语句的“旧数据行”,其中可以获取任何一个字段数据的值,类似这样:
set @v1 = old.id; #获得了旧的id
set @v2 = old.age; #获得了旧的age值
作者: 444786228 时间: 2017-7-8 17:31
可以 简直不要太吊
欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) |
黑马程序员IT技术论坛 X3.2 |