300字范文,内容丰富有趣,生活中的好帮手!
300字范文 > mysql 存储过程 异常 回滚吗_MySQL 5.7 存储过程报错不回滚

mysql 存储过程 异常 回滚吗_MySQL 5.7 存储过程报错不回滚

时间:2019-09-27 20:48:39

相关推荐

mysql 存储过程 异常 回滚吗_MySQL 5.7 存储过程报错不回滚

本人在做项目时,遇到了一个异常蛋疼的问题,困扰了很久。

项目原先的数据库选用的是Oracle,后来到新项目中,换成了MySQL,一些主要的业务操作都是由Procedure来实现完成的。之前写过SqlServer的存储过程没接触过MySQL的。开发过程中,一路顺畅,业务数据流转都很正常。等到部署给客户试用时,频繁的出现死锁、事务不回滚的情况。对于大批量的业务数据出错但不回滚,会持续的产生恶性循环。这篇文章主要用来记录下最近半年对项目维护过程中对存储过程的一些了解。

一、事务不回滚

贴下示例的存储过程

CREATE PROCEDURE procedure_test(

IN in_param1 VARCHAR(100),

IN in_param2 VARCHAR(20),

OUT out_return_code VARCHAR(100)

)

label:BEGIN

DECLARE r_param1 DECIMAL;

-- 定义异常

DECLARE EXIT HANDLER FOR SQLEXCEPTION

BEGIN

GET DIAGNOSTICS CONDITION 1 @P1 = MYSQL_ERRNO,@P2 = MESSAGE_TEXT;

SET out_return_code = CONCAT('999||',@P1,'||',@P2);

ROLLBACK;

END;

START TRANSACTION;-- 开始事务

-- 业务逻辑

SET out_return_code = '******';

CALL procedure_getID('testType',out_return_code);

IF LEFT(out_return_code,3)<>'000' THEN

SET out_return_code ='获取事务ID失败';

ROLLBACK;

LEAVE label;

END IF;

--业务逻辑

COMMIT;-- 事务结束

END label

在客户试运行过程中,业务逻辑的sql发生了错误之后,发现存储过程退出了,但数据没有ROLLBACK。这就很恐怖了,首先补数据就很痛苦。经过了一段时间的测试,一个个业务逻辑代码删除,一条条SQL执行盘错。最终发现,在Procedure中调用另外的Procedure就会发生不回滚的情况。

procedure_getID 这个Procedure中也start transaciton + commit了,因此业务逻辑报错后,虽然调用了ROLLBACK但是procedure_getID的事务提交会影响到当前的Procedure,直接做了提交。后面将procedure_getID中的业务SQL拷贝至当前Procedure之后,发生错误之后就会回滚了。

二、死锁

这个问题目前还在解决中,这个死锁情况不多所以也就得过且过了。但是还是想先记录下,后面解决了再记录下来。目前有三个主要业务用到了一张数据表(t_details)。目前有时间了,准备着手处理这个问题,列出几点分析:

1,t_details索引建立过多,各个Procedure用到的时候没有合理查询条件,考虑用查询需要update/delete的数据的主键,再进行数据的CRUD操作。

2,其中行锁不直接锁记录,而是锁索引,如果一条SQL语句用到了主键索引,MySQL会锁住主键索引;如果一条语句操作了非主键索引,MySQL会先锁住非主键索引,在锁定主键索引。

3,将三个业务的对于t_details的操作拆分成三个业务任务表来分开操作,避免同时执行三个业务时抢资源的情况。

如果有不对的地方,请大佬提点下,多谢~

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。