A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

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


1 个回复

正序浏览
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马