複製鏈接
請複製以下鏈接發送給好友

隊列表

鎖定
隊列”是一種資料的存儲結構,特點是資料先進先出。一個隊列中存儲的內容是按照先進先出規則儲存的若干消息,若干隊列儲存在一個隊列表中。隊列表用於儲存很多來自數據庫系統的消息,包括數據庫如何執行調度各種任務、數據庫的狀態等等。 [1] 
中文名
隊列表
外文名
Queue Table
應用領域
數據庫、數學、計算機等
主要類型
oracle高級隊列
優    點
可以通過PL/SQLJavaC來訪問
特    性
高級隊列管理

隊列表簡介

一般系統的應用可以分為:
立即要執行和可以延遲要執行的事情,區分這個很重要。
為了提高系統的性能,縮短系統等待時間,引入隊列技術。
隊列是一種能將應用程序的處理工作有效地劃分為前台任務和後台任務的技術。當處理容量允許時,這種技術通過存儲消息、確定消息處理的優先順序和嚮應用程序
提交消息來發揮作用。它使你能夠平衡本地計算機的負荷,或將任務分配到遠程計算機。 為了減少用户的等待時間,應用程序可以讓説明需要後台處理的消息排入隊列。然後就可以從頁面的呈遞過程中去掉該處理任務。由一個後台進程來讀取並隊列處理這些消息,或者甚至可以交由一個單獨的系統來處理它們。 隊列可以實現各個系統之間的數據共享,消息通信。

隊列表功能

目的
利用oracle高級隊列實現pl/sql代碼,為其它語言實現高級隊列的功能作接口。
Oracle高級隊列的好處
a、 高級隊列管理是Oracle數據庫的一個特性,它提供消息隊列管理功能。這是一個非常可靠、安全和可伸縮的消息管理系統,因為它使用與其他基於Oracle技術的應用程序相同的數據庫特性。
b 、高級隊列管理的一個很大優點是它可以通過PL/SQLJavaC來訪問,這樣你就可以把來自一個Java servlet的消息入隊列和使PL/SQL存儲過程中的相同消息出隊列。
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] 

隊列表入隊測試

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' ;
參考資料
  • 1.    趙松濤.Oracle 9i中文版數據庫系統管理:人民郵電出版社圖書,2003