版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/lwl2014100338/article/details/83895884
SQL语句
--
#开启定时器,默认为关闭状态
set global event_scheduler =1; #或者set GLOBAL event_scheduler = ON;
use monitorsys;
drop event if exists report_back_exception_2_task;
delimiter $$
create event report_back_exception_2_task
-- 每周五晚上23点运行
ON SCHEDULE EVERY 1 WEEK STARTS DATE_ADD(DATE_ADD('2018-11-09', INTERVAL 1 DAY), INTERVAL -772 MINUTE)
-- show events
-- SELECT DATE_ADD(DATE_ADD('2018-11-08', INTERVAL 1 DAY), INTERVAL -773 MINUTE)
-- SELECT * FROM task_log 6分钟延迟
do
begin
DECLARE t_error INTEGER DEFAULT 0;
DECLARE CONTINUE HANDLER FOR SQLEXCEPTION SET t_error=1; # 异常时为1
#开始数据统计处理事务
start transaction;
set current_date_=NOW();
IF t_error=1 THEN
INSERT INTO task_log(logType,procName,time,msg)
VALUES('event','report_back_exception_2_task',NOW(),'资管/基金:偏离比较基准50bp-100bp的交易统计错误。');
ROLLBACK;
ELSE
INSERT INTO task_log(logType,procName,time,msg)
VALUES('event','report_back_exception_2_task',NOW(),'资管/基金:偏离比较基准50bp-100bp的交易统计运行成功!');
COMMIT;
END IF;
end $$
delimiter ;
我认为的执行结果:task_log表中新增一条数据
INSERT INTO task_log(logType,procName,time,msg)
VALUES('event','report_back_exception_2_task',NOW(),'资管/基金:偏离比较基准50bp-100bp的交易统计运行成功!');
实际执行结果:没有插入任何数据
排查过程
(1) 注释掉开始事物的SQL
-- start transaction;
执行结果:没有插入任何数据
(2)注释掉时间的SQL
-- set current_date_=NOW();
执行结果: 正常插入数据
INSERT INTO task_log(logType,procName,time,msg)
VALUES('event','report_back_exception_2_task',NOW(),'资管/基金:偏离比较基准50bp-100bp的交易统计运行成功!');
疑问
为啥日期赋值语句SQL报错不被捕获,没有进入if语句,直接停止往下执行
解答
(1)日期类型长度为varchar(12),now()的长度为19,所以日期数据赋值失败
(2)MySQL在默认情况 下(也就是我们没有定义处理错误的方法-handler)自己的错误处理机制,对于SQLWARNING和NOT FOUND的处理方法就是无视错误继续执行。对于SQLEXCEPTION的话,其默认的处理方法是在出现错误的地方就终止掉了。
(3)使用START TRANSACTION,自动提交将保持禁用状态,直到你使用COMMIT或ROLLBACK结束事务。一句话来说就是,手动开启事物要手动关闭。
IF t_error=1 THEN
ROLLBACK;
INSERT INTO task_log(logType,procName,time,msg)
VALUES('event','report_back_exception_2_task',NOW(),'sqlexception异常。');
(4)使用START TRANSACTION开启事物,不提交也不回滚,会直接导致死锁
提示:注意会话隔离