例子
-- 秒殺執(zhí)行存儲(chǔ)過程 DELIMITER $$ -- 將分隔符; 轉(zhuǎn)換為 $$ -- 定義存儲(chǔ)過程 -- 參數(shù): in 輸入?yún)?shù); out 輸出參數(shù) -- row_count():返回上一條修改類型sql(delete,insert,update)的影響行數(shù) -- row_count: 0:未修改數(shù)據(jù); >0:表示修改的行數(shù); <0:sql錯(cuò)誤/未執(zhí)行修改sql CREATE PROCEDURE `seckill`.`execute_seckill` (in v_seckill_id bigint,in v_phone bigint, in v_kill_time timestamp,out r_result int)--創(chuàng)建儲(chǔ)存過程 BEGIN-- 開始執(zhí)行 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);--執(zhí)行insert語句 select row_count() into insert_count;--返回影響行數(shù) IF (insert_count = 0) THEN ROLLBACK;--事務(wù)回滾 set r_result = -1;--返回未修改數(shù)據(jù) ELSEIF(insert_count < 0) THEN ROLLBACK;--事務(wù)回滾 set R_RESULT = -2;--返回未知錯(cuò)誤 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;--執(zhí)行update語句 select row_count() into insert_count;--返回影響行數(shù) IF (insert_count = 0) THEN ROLLBACK;--事務(wù)回滾 set r_result = 0;--返回未修改數(shù)據(jù) ELSEIF (insert_count < 0) THEN ROLLBACK;--事務(wù)回滾 set r_result = -2;--返回未知錯(cuò)誤 ELSE COMMIT;--提交,事務(wù)結(jié)束 set r_result = 1;--返回執(zhí)行成功 END IF;--結(jié)束IF語句 END IF;--結(jié)束IF語句 END;--結(jié)束儲(chǔ)存過程 $$--結(jié)束sql -- 存儲(chǔ)過程定義結(jié)束 DELIMITER ;--還原分隔符為; -- set @r_result=-3;--定義用戶變量 -- 執(zhí)行存儲(chǔ)過程 call execute_seckill(1003,13502178891,now(),@r_result); -- 獲取結(jié)果 select @r_result; -- 存儲(chǔ)過程 -- 1:存儲(chǔ)過程優(yōu)化:事務(wù)行級鎖持有的時(shí)間 -- 2:不要過度依賴存儲(chǔ)過程 -- 3:簡單的邏輯可以應(yīng)用存儲(chǔ)過程 -- 4:QPS:一個(gè)秒殺單6000/qps
1.儲(chǔ)存過程參數(shù)
- IN:參數(shù)的值必須在調(diào)用存儲(chǔ)過程時(shí)指定,在存儲(chǔ)過程中修改該參數(shù)的值不能被返回,為默認(rèn)值
- OUT:該值可在存儲(chǔ)過程內(nèi)部被改變,并可返回
- INOUT:調(diào)用時(shí)指定,并且可被改變和返回
- [IN|OUT|INOUT] 參數(shù)名 數(shù)據(jù)類型
- 比如: IN number INT
- 例子:
DELIMITER // CREATE PROCEDURE myproc(OUT s int) BEGIN SELECT COUNT(*) INTO s FROM students; END // DELIMITER ;
2.Mybatis調(diào)用儲(chǔ)存過程
<!-- statementType 聲明指向的是什么類型,其中CALLABLE是執(zhí)行存儲(chǔ)過程和函數(shù)的--> <select id="killByProcedure" parameterType="map" statementType="CALLABLE"> call execute_seckill( #{seckillId,jdbcType=BIGINT,mode=IN}, #{phone,jdbcType=BIGINT,mode=IN}, #{killTime,jdbcType=TIMESTAMP,mode=IN}, #{result,jdbcType=INTEGER,mode=OUT} ) </select>
原文鏈接:http://suo.im/4p3v48 作者:薛勤