当你决定使用存储过程的时候,那么整个事务是在MYSQL端完成的。
对于事务竞争优化的主要一点就是减少事务锁时间。
你选择了使用存储过程就可以不用再代码中开启事务,深度优化即将事务SQL在MYSQL端执行(存储过程)
以下是类似的秒杀事务落地的存储过程
-- 秒杀执行存储过程
DELIMITER $$ -- ; 转换为 $$
-- 定义存储过程 in 输入参数 out 输出参数
-- ROW_COUNT 返回上一条修改类型sql(delete、insert、update)的影响函数
-- row_count 0 未修改数据 >0修改的函数 <0 SQL错误、未执行修改sql
CREATE 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;
这属于并发优化的阶段了,不要过度依赖存储过程,其一般用于简单的逻辑