猿问

mysql的存储过程会自动开启一个事务吗?

mysql的存储过程会自动开启一个事务吗

有一段代码,这段代码开启了事务,整个请求就开启了这一个事务,这个事务中间有调用一个存储过程,这个存储过程就是更新了一些数据,存储过程里面是没有显示开启事务的,就begin,end就完了。
这个事务里面有更新一条数据,执行完后,代码里面又有个操作去更新存储过程里面刚刚更新过了的同一条数据,这里就发生了锁等待超时了。


我想问的是,调用执行存储过程,存储过程里面没有开启事务,它会自动开启一个新的事务吗?而且没有自动提交。
导致后面操作相同数据的时候拿不到锁。

我通过查看MySQL的锁情况和代码测试,发现确实是存储过程开启了一个新的事务,执行完后也没有提交,一直挂在那里。


qq_笑_17
浏览 2044回答 1
1回答

倚天杖

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