因公司專案中有個贈送優惠券功能,此功能需求為:贈送出去的優惠券若24小時內沒有被領取,則自動設定為贈送失敗(過期未被領取),優惠券自動退換給贈送者。
初步想法是:在mysql中建立儲存過程進行業務邏輯判斷以及操作庫,然後使用事件定時的調取儲存過程,即可完成需求。
一、建立事件
1.、事件簡單描述就是可以定時的執行乙個任務,最大的優點是:一些定時操作不在依賴外部程式,而直接使用資料庫的自身提供的功能完成,可以實現每秒鐘執行乙個任務,這對一些實時性要求很高的環境就非常實用。缺點是:不可以手動呼叫,定時觸發。
2、首先檢視mysql是否開始事件
2.1 檢視資料庫是否開始事件
show variables like "event_scheduler";
查詢結果如下:
2.2 如果value = off 則需要通過如下任何乙個命令進行事件的開啟(若要關閉則為 0 或者 off):
set global event_scheduler = on;
set @@global.event_scheduler = on;
set global event_scheduler = 1;
set @@global.event_scheduler = 1;
通過配置檔案my.conf(若要關閉則為 0 或者 off)
event_scheduler = 1 #或者on
3、建立事件event
delimiter $$
-- set global event_scheduler = on$$ -- required for event to execute but not create
create /*[definer = ]*/ event `weishop`.`e_return_conpon`
on schedule
/* uncomment the example below you want to use */
-- scheduleexample 1: run once
-- at 'yyyy-mm-dd hh:mm.ss'/current_timestamp
-- scheduleexample 2: run at intervals forever after creation
-- every 1 [hour|month|week|day|minute|...]
-- scheduleexample 3: specified start time, end time and interval for execution
/*every 1 [hour|month|week|day|minute|...]
starts current_timestamp/'yyyy-mm-dd hh:mm.ss'
ends current_timestamp/'yyyy-mm-dd hh:mm.ss' */
/*[on completion [not] preserve]
[enable | disable]
[comment 'comment']*/
every 30 minute
do begin
call p_return_coupon();
end$$
delimiter ;
4、名詞解釋: database_name:資料庫名稱
event_name:事件名稱(唯一性)
on schedule:計畫任務
schedule:決定event的執行時間和頻率(注意時間一定是將來的時間,過去的時間會報錯),有兩種形式at 和 every。
[on completion [not] preserve]:可選項,預設是 on completion not preserve 即計畫任務執行完畢自動 drop 該事
件,on completion preserve 則不會 drop 掉。
[comment 'comment']: 可選項,注釋。
[enable||disable]:設定event的狀態,預設 enable :表示系統嘗試執行這個事件,disable:關閉改事件,可通過
alter:命令修改。
do event_body:需要執行的sql語句,可以是復合sql,亦可以呼叫儲存過程 procedure。
我們在上面建立了乙個event,每隔30分鐘呼叫一次 p_return_coupon 儲存過程。
二、建立儲存過程 p_return_coupon
1、儲存過程的介紹:簡單來說,儲存過程就是為以後的使用而儲存的一條或者多條mysql語句的集合,儲存過程中有業務邏
輯和流程的集合,可以在儲存過程中建立表,更新資料,刪除等等。
2、為什麼需要使用儲存過程:
2.1、通過把複雜的業務封裝成乙個單元,簡化操作,程式中只需要 呼叫儲存過程處理,比起單條 sql 執行,**量和效
率會有所改善。
2.2、在生產環境可以直接修改儲存過程來處理bug,不需要重啟伺服器(前提是修改的儲存過程需要進行詳細的測試)。
2.3、方便業務的變更維護,如果表明和列名發生變化,只需要修改儲存過程,不用改變任何**。
3、建立儲存過程
delimiter $$
create
/*[definer = ]*/
procedure `weishop`.`p_return_coupon`()
/*language sql
| [not] deterministic
| | sql security
| comment 'string'*/
begin
-- 宣告乙個標誌done,用來判斷游標是否遍歷完成
declare done int default 0;
-- 宣告乙個變數,用來存放從游標中提取的資料
declare cid int;
declare ctime datetime;
-- 宣告乙個游標
declare cur cursor for select m.id from member_coupon m inner join given_record g on m.id = g.coupon_id where m.status = 3 and g.orders = 1 and g.create_date is not null;
-- 在游標迴圈到最後會將 done 設定為 1(如果不加該行 游標為空的時候 就會報錯)
declare continue handler for not found set done = 1;
-- 開啟游標
open cur;
-- 開始迴圈
repeat
-- 游標的每一次迴圈值賦值給cid變數
fetch cur into cid;
-- 如果游標沒有結束
if not done then
-- 根據cid將找到的create_date賦值給ctime變數
select create_date into ctime from given_record where orders = 1 and coupon_id = cid;
-- 如果ctime變數加上5分鐘小於當前時間則進行更新操作
if date_add(ctime, interval 5 minute)< now() then
update member_coupon set status = 1 where status = 3 and id = cid;
update given_record set orders = 3 where orders = 1 and coupon_id = cid;
end if;
end if;
until done end repeat;
close cur;
end$$
delimiter ;
4、其中使用到了游標 cursor 和 迴圈 repeat,我們下節進行描述。
三、結束語:這樣的話就可以通過事件每隔30分鐘呼叫儲存過程來處理若5分鐘未被領取則歸還贈送者業務!
歡迎指正。
mysql儲存過程中使用事件
create definer root localhost procedure createbusiness parameter1 int begin routine body goes here.declare flag int default parameter1 宣告變數flag,將引數值賦給...
mysql儲存過程中使用事務
mysql儲存過程中使用事務 1 drop procedure ifexists test sp1 2create procedure test sp1 3begin 4declare t error integer default 0 5declare continue handler for s...
儲存過程中使用事務
create procedure updatewanjun username nvarchar 500 userpassword nvarchar 500 returnval int output as set xact abort on begin transaction t update adm...