DELIMITER $$ -- 将默认换行分割符;换成$$
-- 定义存储过程
-- 参数:in 输入参数 out 输出参数
-- row_count():返回上一条修改类型sql(insert、update、delete)的影响行数
-- 返回结果:0 未修改数据 >0 影响行数 <0 sql错误/未执行修改sqlCREATE PROCEDURE `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;
-- mysql 中 执行存储过程
call execute_seckill(1003, 18701321850, now(), @r_result);
java后台使用存储过程
service:(SeckillExecution是秒杀状态对象)
public SeckillExecution executeSeckillProcedure(long seckillId, long userPhone) {
Date killTime = new Date();
Map<String, Object> map = new HashMap<>();
map.put("seckillId", seckillId);
map.put("phone", userPhone);
map.put("killTime", killTime);
map.put("result", null);
secKillDao.killByProceduce(map);
//获取result
int result = MapUtils.getInteger(map, "result", -2);
if (result == 1) {
//秒杀抢购成功
return 成功状态;
} esle {
return 失败状态;
}
}
dao: void killByProceduce(Map<String, Object> paramMap);
mybatis调用存储过程:
<select id="killByProcedure" statementType="CALLABLE">
call execute_seckill (
#{seckillId, jdbcType=BIGINT,mode=IN},
#{phone, jdbcType=BIGINT,mode=IN},
#{killTime, jdbcType=TIMESTAMP,mode=IN},
#{result, jdbcType=BIGINT,mode=OUT}
)
</select>MapUtils的依赖:
<dependency>
<groupId>commons-collections</groupId>
<artifactId>commons-collections</artifactId>
<version>3.2.1</version>
</dependency>