本帖最后由 小鲁哥哥 于 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值
|