基本介紹
簡介,功能,創建佇列,入隊測試,出隊測試,
簡介
一般系統的套用可以分為:
立即要執行和可以延遲要執行的事情,區分這個很重要。
為了提高系統的性能,縮短系統等待時間,引入佇列技術。
佇列是一種能將應用程式的處理工作有效地劃分為前台任務和後台任務的技術。當處理容量允許時,這種技術通過存儲訊息、確定訊息處理的優先順序和向應用程式
提交訊息來發揮作用。它使你能夠平衡本地計算機的負荷,或將任務分配到遠程計算機。 為了減少用戶的等待時間,應用程式可以讓說明需要後台處理的訊息排入佇列。然後就可以從頁面的呈遞過程中去掉該處理任務。由一個後台進程來讀取並佇列處理這些訊息,或者甚至可以交由一個單獨的系統來處理它們。 佇列可以實現各個系統之間的數據共享,訊息通信。
功能
目的
Oracle高級佇列的好處
a、 高級佇列管理是Oracle資料庫的一個特性,它提供訊息佇列管理功能。這是一個非常可靠、安全和可伸縮的訊息管理系統,因為它使用與其他基於Oracle技術的應用程式相同的資料庫特性。
c 、高級佇列管理的另一個優點是你可以利用這一軟體通過Oracle Net Services (SQL*Net)、HTTP(S)和SMTP,在遠程節點之間傳播訊息。高級佇列甚至可以通過訊息網關與非Oracle的訊息管理系統(如IBMMQSeries)相集成。
d 、Oracle高級佇列管理提供了單消費者佇列和多消費者佇列。單消費者佇列只面向單一的接收者。多消費者佇列可以被多個接收者使用。當把訊息放入多消費者佇列時,應用程式的程式設計師必須顯式地在訊息屬性中指定這些接收者,或者建立決定每條訊息的接收者的基於規則的訂閱過程。
佇列的開發
佇列的管理和佇列的操作。
具體開發步驟
a 、首先確定套用的需求,是否適合使用高級佇列?使用高級佇列預計提高性能的預期值
b 、確定佇列包體結構。
c 、佇列管理。
d 、佇列操作。
創建佇列
1、授予測試用戶相應的許可權
Grant aq_administrator_role To testuser;
grant execute on sys.dbms_aq To testuser;
grant execute on sys.dbms_aq_admin To testuser;
2、創建源數據表並插入測試數據
CREATE table mt_struc_t
( id number(5) ,
name varchar2(30),
age varchar2(30)
)
insert into mt_struc_t values(1,'aaa','10');
insert into mt_struc_t values(2,'bbb','20');
insert into mt_struc_t values(3,'ccc','30');
3、創建一個集合類型的對象
CREATE OR REPLACE Type mt_struc As Object
( id number(5) ,
name varchar2(30),
age varchar2(30)
)
4、創建佇列表
begin
sys.dbms_aqadm.create_queue_table(queue_table=>'sms_mt_tab',queue_payload_type=>'mt_struc');
end ;
--此時你再查看該表,看看其結構與普通表有什麼異同
select * from sms_mt_tab ;
5、創建佇列
begin
sys.dbms_aqadm.create_queue(queue_name=>'sms_mt_queue', queue_table=>'sms_mt_tab');
sys.dbms_aqadm.create_queue(queue_name=>'sms_mt_queue_exception',queue_table=>'sms_mt_tab',queue_type=>sys.dbms_aqadm.EXCEPTION_QUEUE);
sys.dbms_aqadm.create_queue(queue_name=>'sms_mt_queue_backup', queue_table=>'sms_mt_tab');
end ;
入隊測試
1、創建入隊的存儲過程,定義入隊的方法
create or replace procedure proc_test_in( p_equeue_name In varchar2, --佇列名單大寫字母,主佇列:SMS_MT_QUEUE 備份佇列:SMS_MT_QUEUE_BACKUP
p_body In mt_struc_t%Rowtype,--入參,記錄類型,數據源頭直接調用(引用類型)
p_level In Number:=3, --優先權別1-5,數值越小越快
p_delay In Number:=0, --入隊延遲時間,單位:秒
p_res_str OUT VARCHAR2, --0 成功 其它失敗
p_msg_id OUT Varchar2 --返回的msgid,主鍵
)
Is
v_enqueue_options sys.dbms_aq.enqueue_options_t;
v_message_properties sys.dbms_aq.message_properties_t;
v_body mt_struc;---之前定義的集合類型
v_message_handle raw(16);
begin
p_res_str:='正常';
v_body:=mt_struc(p_body.id ,
p_body.name ,
p_body.age ) ;
--4設定屬性和參數---
--指定異常佇列
v_message_properties.exception_queue:='SMS_MT_QUEUE_EXCEPTION';
--設定優先權別
v_message_properties.priority :=p_level;
--設定延時時間--秒
v_message_properties.delay :=p_delay;
sys.dbms_aqadm.start_queue(p_equeue_name,enqueue=>true, dequeue=> true); --第一個參數是傳進來的佇列名
sys.dbms_aq.enqueue(queue_name=>p_equeue_name,
enqueue_options=>v_enqueue_options,
message_properties=>v_message_properties,
payload=>v_body,
msgid=>v_message_handle);
P_MSG_ID:=v_message_handle ;
Commit;
p_res_str:='0';
Exception
When Others Then
p_res_str:='異常';
Rollback;
end proc_test_in;
2、根據實際需要,創建一個調用入入隊方法的存儲過程,將源表的值入隊
create or replace procedure proc_test_in_call(
p_equeue_name In varchar2,--佇列名單大寫字母,主佇列:SMS_MT_QUEUE 備份佇列:SMS_MT_QUEUE_BACKUP
p_res_str out Varchar2,
p_msg_id OUT Varchar2
) /*
功能:測試入隊
*/
Is
Cursor cur_push Is
Select * From mt_struc_t;
v_row_push mt_struc_t%Rowtype;
v_exe_res varchar2(200);
v_message_handle raw(16);
begin
p_res_str:='-1';
Open cur_push;
Loop
Fetch cur_push Into v_row_push;
Exit When cur_push%Notfound;
proc_test_in(p_equeue_name,v_row_push,3,0,v_exe_res,v_message_handle);
End Loop;
Close cur_push;
p_res_str:=v_exe_res;
p_msg_id:=v_message_handle;
Exception
When Others Then
p_res_str:=Sqlerrm;
Rollback;
end proc_test_in_call;
3、執行入隊
declare
p_res_str VARCHAR2(200); --0 成功 其它失敗
p_msg_id Varchar2 (200); --返回的msgid,主鍵
begin
proc_test_in_call('sms_mt_queue',p_res_str,p_msg_id);
dbms_output.put_line(p_res_str ||''||p_msg_id);
end ;
---注、執行本匿名快,數據將被寫入佇列,此時你可以查看out參數的返回值
以及查看佇列表是否有值(以上測試成功)
select * from sms_mt_tab ; ---對列表
Select Count(1) From sms_mt_tab Where q_name='SMS_MT_QUEUE' ; --不同的佇列可以控制不同的訊息入隊
出隊測試
(將存入佇列的值拿出去,並得到相應的返回值)
1、創建出隊的過程(方法)
create or replace procedure proc_test_out
(
p_equeue_name In varchar2, --佇列名單大寫字母,主佇列:SMS_MT_QUEUE 備份佇列:SMS_MT_QUEUE_BACKUP
p_id Out number,
p_name out varchar2,
p_age out varchar2)
Is/*
功能: 出佇列,返回給java程式
*/
v_Dequeue_Options Dbms_Aq.Dequeue_Options_t;
v_Message_Properties Dbms_Aq.Message_Properties_t;
v_Message_Handle Raw(16);
v_Body_queue Mt_Struc;
---寫日誌區域
vProTip VARCHAR2(255);
vErrorCode VARCHAR2(20);
vErrorMsg VARCHAR2(2000);
v_count Number;
Begin
---執行出佇列操作
Select Count(0) Into v_count From sms_mt_tab Where q_name=p_equeue_name ;
If v_count >0 Then
dbms_aqadm.start_queue(p_equeue_name,enqueue=>true, dequeue=> true);
Dbms_Aq.Dequeue(Queue_Name => p_equeue_name,
Dequeue_Options => v_Dequeue_Options,
Message_Properties => v_Message_Properties,
Payload => v_Body_queue,
Msgid => v_Message_Handle);
p_id := v_Body_queue.id ;
p_name :=v_Body_queue.name ;
p_age := v_Body_queue.age ;
Commit;
End If;
Exception
When Others Then
vProTip:='出隊過程異常!';
vErrorCode:=SQLCODE;
vErrorMsg:=SQLERRM;
Rollback;
end proc_test_out;
-------------
2、出隊測試(將佇列返回值答應出來了,實際用的時候可以傳給對應的變數)
declarep_id number(5);
p_name varchar2(200);
p_age varchar2(200);
begin
proc_test_out('SMS_MT_QUEUE',p_id,p_name,p_age);
dbms_output.put_line(p_id||' '||p_name||' '||p_age);
end ;
3、查看佇列表是否有值
(看每執行一次,佇列表的數據是不是少了一條。)select * from mt_struc_t ; ---普通表
select * from sms_mt_tab ; ---對列表
Select Count(1) From sms_mt_tab Where q_name='SMS_MT_QUEUE' ;