mysql的存储过程会自动开启一个事务吗有一段代码,这段代码开启了事务,整个请求就开启了这一个事务,这个事务中间有调用一个存储过程,这个存储过程就是更新了一些数据,存储过程里面是没有显示开启事务的,就begin,end就完了。这个事务里面有更新一条数据,执行完后,代码里面又有个操作去更新存储过程里面刚刚更新过了的同一条数据,这里就发生了锁等待超时了。我想问的是,调用执行存储过程,存储过程里面没有开启事务,它会自动开启一个新的事务吗?而且没有自动提交。导致后面操作相同数据的时候拿不到锁。我通过查看MySQL的锁情况和代码测试,发现确实是存储过程开启了一个新的事务,执行完后也没有提交,一直挂在那里。
1 回答

倚天杖
TA贡献1828条经验 获得超3个赞
当你决定使用存储过程的时候,那么整个事务是在MYSQL端完成的。
对于事务竞争优化的主要一点就是减少事务锁时间。
你选择了使用存储过程就可以不用再代码中开启事务,深度优化即将事务SQL在MYSQL端执行(存储过程)
以下是类似的秒杀事务落地的存储过程
-- 秒杀执行存储过程 DELIMITER $$ -- ; 转换为 $$ -- 定义存储过程 in 输入参数 out 输出参数 -- ROW_COUNT 返回上一条修改类型sql(delete、insert、update)的影响函数 -- row_count 0 未修改数据 >0修改的函数 <0 SQL错误、未执行修改sqlCREATE PROCEDURE `seckill`.`execute_seckill` (in v_seckill_id bigint,in v_phone bigint, in v_kill_time TIMESTAMP ,out r_result int) BEGIN DECLARE insert_count int DEFAULT 0; START TRANSACTION ; insert ignore into success_killed (seckill_id,user_phone,create_time) VALUES (v_seckill_id,v_phone,v_kill_time) select ROW_COUNT() into insert_count; if (insert_count = 0) THEN ROLLBACK; set r_result = -1; ElSEIF(insert_count < 0) THEN ROLLBACK; set r_result = -2; ELSE UPDATE seckill set number = number - 1 where seckill_id = v_seckill_id and end_time > v_kill_time and start_time < v_kill_time and number > 0; SELECT row_count() into insert_count; if (insert_count = 0) THEN ROLLBACK; set r_result = 0; ElSEIF(insert_count < 0) THEN ROLLBACK; set r_result = -2; ELSE COMMIT; SET r_result = 1; END if; END if; END; $$ -- 存储过程定义结束 DELIMITER ;set @r_result=-3; -- 执行存储过程 call execute_seckill(1003,18820116735,now(),@r_result); -- 获取结果select @r_result;
这属于并发优化的阶段了,不要过度依赖存储过程,其一般用于简单的逻辑
- 1 回答
- 0 关注
- 2043 浏览
添加回答
举报
0/150
提交
取消