Este artigo tem por finalidade introduzir os comandos básicos na utilização do recurso de Queue do Oracle chamado Advanced Queue.
Vamos utilizar um schema do banco de dados Oracle chamado CATROQUE . Nele criaremos todos os recursos necessários para o funcionamento do Oracle Advanced Queue.
Para possibilitar a utilização de queues nosso schema deve conter permissões de execução em packages específicas do Oracle: DBMS_AQADM e DBMS_AQ. Somante o schema administrador da queue deverá conter permissões a package DBMS_AQADM.
--
-- Script para habilitação de AQ ao usuário. Deve ser executado
-- pelo usuário SYSTEM.
--
GRANT EXECUTE ON DBMS_AQADM TO CATROQUE;
GRANT EXECUTE ON DBMS_AQ TO CATROQUE;
Temos que estabelecer qual a formação de conteúdo das mensagens que iremos utilizar nas queues do sistema através de um tipo. Neste artigo apenas estabeleceremos 1 (uma) única mensagem chamada TYP_MENSAGEM_PEDIDO.
--
-- Criando a infraestrutura de queue. Deve ser executado pelo usuário
-- administrador ou operador da queue.
--
CREATE OR REPLACE TYPE TYP_MENSAGEM_PEDIDO
AS OBJECT
(
TIP_ACAO NUMBER(5),
PEDIDO_UID NUMBER(12),
CLIENTE_UID NUMBER(12)
);
Podemos criar uma package para abrigar as constantes que serão utilizadas na identificação do tipo de ação em cada mensagem.
CREATE OR REPLACE PACKAGE "PKG_CONSTANTE"
AS
DTIP_ACAO_NOVO CONSTANT NUMBER(5) := 0;
DTIP_ACAO_ALTERACAO CONSTANT NUMBER(5) := 1;
DTIP_ACAO_CANCELAMENTO CONSTANT NUMBER(5) := 2;
END KRISK_CONSTANTE;
Neste momento já temos a estrutura da mensagem que será trafegada entre as queues. Passemos a criar a tabela de controle das mensagens que as queues usarão.
--
-- Criação de uma tabela de controle para queues de mensagem
--
BEGIN
DBMS_AQADM.CREATE_QUEUE_TABLE(
queue_table => 'CATROQUE.TQUEUE_MENSAGEM_PEDIDO',
queue_payload_type => 'CATROQUE.TYP_MENSAGEM_PEDIDO',
sort_list => 'PRIORITY,ENQ_TIME',
COMMENT => 'Tabela para a Queue de mensagens de pedidos recebido pelo sistema e que serão distribuidos para fila de processamento'
);
END;
Uma vez que já temos a tabela de controle das mensagens, podemos criar as queues que serão utilizadas pela aplicação. Neste artigo criaremos apenas 1 (uma) queue chamada QUEUE_OP1, que será utilizada posteriormente tanto para envio quanto recebimento de mensagens a título de exemplo.
--
-- Criação de uma queue
--
BEGIN
DBMS_AQADM.CREATE_QUEUE (
queue_name => 'CATROQUE.QUEUE_OP1',
queue_table => 'CATROQUE.TQUEUE_MENSAGEM_PEDIDO',
COMMENT => 'Queue de operação número 001'
);
END;
Para colocar em operação a queue criada temos que inicializá-la.
--
-- Inicializar a operação de uma queue
--
BEGIN
DBMS_AQADM.START_QUEUE (
queue_name => 'CATROQUE.QUEUE_OP1',
enqueue => TRUE,
dequeue => TRUE
);
END;
Vamos enfileirar uma mensagem na queue criada.
DECLARE
enqueue_options DBMS_AQ.enqueue_options_t;
message_properties DBMS_AQ.message_properties_t;
message_handle RAW(16);
MESSAGE TYP_MENSAGEM_PEDIDO;
BEGIN
MESSAGE := TYP_MENSAGEM_PEDIDO(PKG_CONSTANTE.DTIP_ACAO_NOVO, 1, 1);
DBMS_AQ.ENQUEUE (
queue_name => 'CATROQUE.QUEUE_OP1',
enqueue_options => enqueue_options,
message_properties => message_properties,
payload => MESSAGE,
msgid => message_handle
);
COMMIT;
END;
Para recuperarmos a primeira mensagem da queue:
DECLARE
dequeue_options DBMS_AQ.dequeue_options_t;
message_properties DBMS_AQ.message_properties_t;
message_handle RAW(16);
MESSAGE TYP_MENSAGEM_PEDIDO;
BEGIN
DBMS_AQ.DEQUEUE(
queue_name => 'CATROQUE.QUEUE_OP1',
dequeue_options => dequeue_options,
message_properties => message_properties,
payload => MESSAGE,
msgid => message_handle
);
DBMS_OUTPUT.PUT_LINE ('Message: ' || MESSAGE.TIP_ACAO || ' ... ' || MESSAGE.PEDIDO_UID || ' ... ' || MESSAGE.CLIENTE_UID );
COMMIT;
END;
Podemos parar a operação da queue através do comando:
--
-- Parar a queue.
--
BEGIN
DBMS_AQADM.STOP_QUEUE(
queue_name => 'CATROQUE.QUEUE_OP1',
);
END;
Para remover a queue do banco de dados:
--
-- Remover a queue
--
BEGIN
DBMS_AQADM.DROP_QUEUE(
queue_name => 'CATROQUE.QUEUE_OP1',
);
END;
Algo mais raro, porém possível é a remoção da tabela de controle da queue:
--
-- Remoção da tabela de controle da queue
--
BEGIN
DBMS_AQADM.DROP_QUEUE_TABLE(
queue_table => 'CATROQUE.TQUEUE_MENSAGEM_PEDIDO',
force => TRUE
);
END;
Mais informações poderão ser obtidas nos seguintes sites:
http://www.oracle.com/pls/db102/portal.portal_db?selected=3
http://docs.oracle.com/cd/B10501_01/appdev.920/a96587/apexampl.htm