六天玩转Mysql(第六天)

事务安全

    免费的存储引擎中只有innodb是支持事务的,其他的并不支持。

事务原理

原理:事务开启之后,所有的操作都会临时保存到事务日志,事务日志只有在得到commit命令才会同步到数据表,其他任何情况都会清空(rollback,断电,断开连接)

回滚点

在某个成功的操作完成之后,后续的操作有可能成功有可能失败,但是不管成功还是失败,前面操作都已经成功,可以在当前成功的位置,放置一个点,可以供后续失败操作返回到该位置,而不是返回所有操作,这个点称之为回滚点。

设置回滚点语法:savepoint 回滚点名字;

回到回滚点语法:rollback to 回滚点名字;

自动事务

自动事务:系统通过autocommit变量控制

show variables like 'autocomment';
--关闭自动提交
set autocommit = off/0;

事务的四大特性

  • A:Atomic 原子性,事务的整个操作是一个整体,不可分割,要么全部成功,要么全部失败
  • C:Consistency一致性,事务操作的前后,数据表中的数据没有变化
  • I:Isolation隔离性,事务操作是相互隔离不受影响
  • D:Durability持久性,数据一旦提交,不可改变,永久的改变数据表数据

事务的隔离级别

未提交读(脏读):当一个A用户,读到了B用户未提交的数据。比如,B账户减了100,但是没有提交事务,A用户查询B用户时,会发现减了100,如果事务不提交,回滚,再次查询是没有减少的。

提交读(不可重复读,大多数数据库默认的,但不是mysql数据库的):一个事务范围内多次查询却返回不同的数据值,这是由于在查询间隔,被另一个事务修改并提交了。

脏读和不可重复读的区别

  • 脏读:某一事务读取了另一事务未提交的脏数据。
  • 不可重复读:读取了前一事务提交的事务,可能结果不同

虚读和幻读

  • 虚读:事务1是读取某一数据后,事务2对其进行了修改,当事务1再次读取的时候,得到与前一次不同的值
  • 幻读:事务在操作过程中进行两次查询,第二次查询的结果比第一次查询多了或少了几条数据

可重复读(mysql默认的)

  • 多次读取到的数据是一致的结果,可重复读可能会导致幻读。
  • 幻读,简单的说就是当用户读取某一范围的数据时,另一个事务又在该范围插入了新行,当用户再次读取时,会发现新的“幻影”行       

可串行化:最高级别的隔离,强制事务进行排序,使之不会冲突,从而解决了幻读问题。在每个读的数据行加上读锁,可能导致大量的超时和锁消耗

锁机制

  • 锁机制:innodb默认是行锁,但是如果在事务操作的过程中,没有使用到索引,那么系统会自动全表检索数据,自动升级为表锁。
  • 行锁:只有当前行被锁住,别的用户不能操作
  • 表锁:整张表被锁住,别的用户都不能操作

Mysql数据库的自动提交

--mysql默认是自动提交
select @@autocommit;

--修改为手动提交
set autocommit = 0;

表锁定

--这个表所有人都只能读取,不能写操作
lock table 表名 read;
--解锁所有表
unlock tables;
--写锁定,这个表自己这个线程可以写和读,但是别的线程只能写操作。
lock table 表名 write;

事务的操作是针对数据的操作,不是针对结构的操作。如果删除了一个表,然后回滚,表还是会被删除的。

变量(系统变量)

--查看所有系统变量
show variables;
--查看系统变量值
select @@version,@@autocommit,@@auto_increment_offset;
--修改会话级别变量
set autocommit = 0;

修改系统变量分为两种方式:会话级别和全局级别

  • 会话级别:临时修改,当前客户端当次连接有效
set 变量名 = 值;set @@变量名 = 值;
  • 全局级别:一次修改,永久生效(对所有客户端都生效)
set global 变量名 = 值;

如果客户端当前已经连上服务器,那么当次修改无效,要退出重新登录才会生效。

变量(自定义变量)

定义变量

系统为了区分系统变量,规定用户自定义变量必须使用一个@符号

set @变量名 = 值;

自定义变量也是类似系统变量查看

select @变量名

在MySQL中,"="会默认的当做比较符号处理(很多地方),MySQL为了区分比较和赋值的概念,重新定义了一个新的赋值符号“:=

方案1:边赋值,边查看结果

select @变量名 :=字段名 from 数据源;

--从字段中取值赋值给变量名,如果使用=会变成比较

触发器

触发器:trigger,事先为某张表绑定好一段代码,当表中的某些内容发生改变的时候(增删改),系统会自动触发代码执行。

触发器:事件类型、触发事件、触发对象

  • 事件类型:增删改,三种类型 insert,delete和update
  • 触发时间:前后:before和after
  • 触发对象:表中的每一条记录(行)

一张表中只能拥有一种触发时间的一种类型的触发器,最多一张表能有6个触发器。

创建触发器

触发器基本语法

--临时修改语句结束符
delimiter --自定义符号:后续代码中只有碰到自定义符号才算结束
create trigger 触发器名字 触发器时间 事件类型 on 表名 for each row
begin     --代表左大括号,开始
           --里面就是触发器的内容,每行内容都必须使用语句结束符:分号
end        --代表右大括号,结束
--语句结束符
自定义符号

--将临时修改修正过来
Delimiter;
delimiter $$
create trigger after_order after insert on my_order for each r
begin
     --触发器内容开始
     update my_goods set inv = inv -1 where id = 2;
end
--结束触发器
$$
--修改临时语句结束符
delimiter;

可以查看触发器创建语句

show create trigger 触发器名字;

触发器不能修改,只能先删除,后新增

drop trigger 触发器名字;

代码执行结构之分支结构

在MySQL中只有if分支

基本语法

if 条件判断 then

   --满足条件要执行的代码

else

  --不满足条件要执行的代码

end if;

代码执行结构之循环结构

while 循环(没有for循环)

while 条件判断 do

     -- 满足条件要执行的代码

     -- 变更循环条件

end while;

循环控制:在循环内部进行循环判断和控制

MySQL中没有对应continue和break,但是有替代品

Iterate:迭代,类似continue,后面的代码不执行,循环重新来过

Leave:离开,类似break,整个循环结束

函数

讲一段代码块封装到一个结构中,在需要执行代码块的时候,调用结构执行即可(代码复用)

函数分为两类:系统函数和自定义函数

自定义函数

函数要素:函数名,参数列表(形参和实参),返回值,函数体(作用域)

--创建语法
create funtion 函数名([形参列表]) return 数据类型 --规定要返回的数据类型
begin
   --函数体
   --返回值:return 类型(指定数据类型);
end

--创建函数
create funtion display1() returns int
return 100;

注意是returns,不是return

删除函数(函数只能先删除后新增,不能修改

语法:Drop function 函数名;

查看函数

查看函数的创建语句

函数的参数

参数分为两种:

    定义的参数为形参,调用时的参数叫实参(实参可以是数值也可以是变量),形参:要求必须指定数据类型

function 函数名(形参名字 字段类型)returns 数据类型

作用域

        MySQL中的作用域与js中的作用域完全一样。全局变量可以在任何地方使用;局部变量只能再函数内部使用

  • 全局变量:使用set关键字定义,使用@符合标志
  • 局部变量:使用declare关键字声明,没有@符号,所有的局部变量的声明,必须在函数体开始之前

存储过程

    存储过程是一种没有返回值的函数,是一种用来处理数据的方式

create procedure 过程名字([参数列表])
begin
    --过程体
end

调用存储过程

 存储过程没有返回值:select是不能访问的

存储过程有一个专门的调用关键字:call

存储过程只能先删除,后新增

drop procedure 存储过程名;

--drop PROCEDURE pp;
/*******************************************************************************

中文名称: 生成系统健康运行指标

调用方法: SCYW.P_AUTONEWSYSTEMRUNINGTIME

作 者: LIHAIPENG

创建时间: 2016-01-31

输入参数: IN_THISTIME : IMS取值时传入的时间戳

返 回 值: OUT_CODE : 返回类型 1为成功

OUT_MSG :返回错误信息

简要说明:

修改记录:

*******************************************************************************/

create procedure pp(in IN_THISTIME datetime,out OUT_CODE VARCHAR(8),out OUT_MSG VARCHAR(256)) BEGIN

-- 本次取值时间

DECLARE V_THISTIME int;

-- 上次取值时间

DECLARE V_LASTTIME varchar(256);

-- 上次取值

DECLARE V_LASTVALUE varchar(256);

-- 两次取值时间差

DECLARE V_INCREMENT varchar(256);

-- 最新健康时间

DECLARE V_JKSJ varchar(256);

-- IMS集成指标缓存表中健康时长指标的记录条数

DECLARE V_JKZBCOUNT varchar(256);

set V_THISTIME := DATE_FORMAT(IN_THISTIME, 'yyyy-mm-dd hh24:mi:ss');

SELECT COUNT(*)

INTO V_JKZBCOUNT

FROM c_cons c

WHERE c.cons_no = '9854032859';

-- 如果表中没有系统健康时长的记录,则插入一条

IF V_JKZBCOUNT < 1 THEN

INSERT INTO khcnlgl.test

(id, name, date)

VALUES

('BusinessSystemRunningTime',

'系统健康运行时长(s)',

'0');

ELSE

-- 获取上次取值的时间和指标值

SELECT c.cons_name, c.ELEC_ADDR

INTO V_LASTVALUE, V_LASTTIME

FROM c_cons c

WHERE c.cons_no = '9854032859'

AND ROWNUM = 1;



IF V_LASTVALUE IS NULL THEN

set V_LASTVALUE := '0';

END IF;



IF V_LASTTIME IS NULL THEN

-- 如果上次取值时间为空值,说明检修后清空后第一次ims取值。把取值时间为当前时间

set V_LASTTIME := V_THISTIME;

END IF;

-- -- 求两次取值的时间差

-- SELECT TO_NUMBER(V_THISTIME - V_LASTTIME) * 24 * 60 * 60

-- INTO V_INCREMENT

-- FROM DUAL;

-- -- 如果时间差值小于0则需按0计算

-- IF V_INCREMENT < 0 THEN

-- V_INCREMENT := 0;

-- V_JKSJ := TO_NUMBER(V_LASTVALUE) + V_INCREMENT;

-- ELSE

-- V_JKSJ := TO_NUMBER(V_LASTVALUE) + V_INCREMENT;

-- END IF;

--

-- -- 向IMS集成指标历史记录表中插入上次的指标记录

-- INSERT INTO SCYW.T_DW_JK_IMS_PARAM_HISTORY

-- (OBJ_ID,

-- DEPART_ID,

-- KPINAME,

-- DESCRIPTION,

-- KPIVALUE,

-- OPERATETIME,

-- NOTE,

-- FREQUENCY,

-- MESSAGE,

-- KPIFZ,

-- KPIFM,

-- SFMX)

-- SELECT PKG_GG_UTIL.F_GET_UUID,

-- DEPART_ID,

-- KPINAME,

-- DESCRIPTION,

-- KPIVALUE,

-- OPERATETIME,

-- NOTE,

-- FREQUENCY,

-- MESSAGE,

-- KPIFZ,

-- KPIFM,

-- SFMX

-- FROM SCYW.T_DW_JK_IMS_PARAM

-- WHERE KPINAME = 'BusinessSystemRunningTime';

--

-- -- 更新IMS集成指标缓存表

-- UPDATE SCYW.T_DW_JK_IMS_PARAM

-- SET KPIVALUE = to_char(V_JKSJ), OPERATETIME = V_THISTIME

-- WHERE KPINAME = 'BusinessSystemRunningTime';

--

-- -- 插入日志

-- INSERT INTO SCYW.T_DW_JK_IMS_LOG

-- (OBJ_ID, KPINAME, KEPCAPTION, STARTTIME, ENDTIME, MESSAGE)

-- VALUES

-- (SCYW.PKG_GG_UTIL.F_GET_UUID(),

-- 'BusinessSystemRunningTime',

-- '系统健康运行时长(s)',

-- V_THISTIME,

-- V_THISTIME,

-- '开始时间:' || V_THISTIME || ',当前时间:' || V_THISTIME || ',健康时长:' ||

-- to_char(V_JKSJ));



END IF;

COMMIT;

set OUT_CODE := '1';



-- exception

-- when others then

-- OUT_CODE := '0';

-- OUT_MSG := '错误日志:' || sqlcode || sqlerrm;

-- rollback;

--

-- INSERT INTO T_DW_JK_IMS_LOG

-- (OBJ_ID, KPINAME, KEPCAPTION, STARTTIME, ENDTIME, MESSAGE)

-- VALUES

-- (SCYW.PKG_GG_UTIL.F_GET_UUID(),

-- 'BusinessSystemRunningTime',

-- '系统健康运行时长(s)',

-- V_THISTIME,

-- V_THISTIME,

-- OUT_MSG);

-- COMMIT;

END;
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

芦蒿炒香干

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值