viernes, 4 de mayo de 2012

Colas AQ (II):- Single Consumer Queue

Para configurar cualquier tipo de Cola AQ, lo primero que hay que hacer es configurar los siguientes parámetros en el fichero de inicialización (Vamos! En el init.ora de toda la vida):

GLOBAL_NAMES=TRUE
JOB_QUEUE_INTERVAL =10
JOB_QUEUE_PROCESSES =5
AQ_TM_PROCESSES = 1

 
Estos parámetros son necesarios para que internamente Oracle sea capaz de gestionar los Jobs y los procesos q00x que se levantan a la hora de procesar las COLAS AQ.

El entorno que habría que montar, a nivel de BBDD,  para la creación de una COLA AQ sencilla (Single Consumer Queue, es decir, a un sólo destinatario) Estaría compuesto de los siguientes elementos:

El tipo de Dato.
La Tabla de Encolados.
La Cola.
Los procesos de Encolar y Desencolar.


1.- Creación del Tipo de Dato. 

Como ya se ha dicho, el Tipo de Dato puede ser tan complejo como sea necesario. En este caso se va a realizar un ejemplo para encolar-desencolar las altas que se tramitan entre usuarios. El Tipo de Datos se crea en el Esquema del usuario y un ejemplo de ello puede ser: 

CREATE TYPE altas AS OBJECT
(Codigo      NUMBER(8),
 Nombre      VARCHAR2(20),
 Apellidos   VARCHAR2(30), 
 DNI         NUMBER(8) );

 

 2.- Creación de la Tabla de Encolados (Queue Table)


Una vez creado el Tipo de Datos, ahora tenemos que crear la tabla donde se van a almacenar los datos de la cola. Esta tabla se llama QUEUE TABLE.

Para la creación de esta tabla, se utiliza el procedure CREATE_QUEUE_TABLE del paquete DBMS_AQADM. Dependiendo del tipo de cola a crear, se van a generar una serie de Tablas y Vistas que sólo serán accesibles para consulta y serán modificadas por las API de las colas.

* Nota: Es importante tener en cuenta que para la utilización de los procedures del paquete DBMS_AQADM y el DBMS_AQ, se tiene que tener instalado el paquete de Colas AQ en la BBDD. 

Para instalarlo, se ejecutaría el siguiente script:

SQL > @?/rdbms/admin/dbmsaqad.sql

En nuestro ejemplo, para crear las Queue Table, ejecutaríamos:

BEGIN

dbms_aqadm.create_queue_table (
queue_table=> 'altas_t',             -- nombre de la Queue table
queue_payload_type=> 'altas',        -- Tipo de datos
multiple_consumers=> FALSE,          -- Que es Single Consumers
message_grouping=> DBMS_AQADM.NONE   -- Grupo de Mensajes
);

COMMIT;                            
END;

/

Este procedimiento crearía la tabla ALTAS_T (Nombre que le hemos dado) y  que tendría la siguiente estructura:

SQL > DESC CYRIS.ALTAS_T

Nombre                     ?Nulo? Tipo
------------------------ -------- --------------------
Q_NAME                            VARCHAR2(30)
MSGID                             NOT NULL RAW(16)
CORRID                            VARCHAR2(128)
PRIORITY                          NUMBER
STATE                             NUMBER
DELAY                             DATE
EXPIRATION                        NUMBER
TIME_MANAGER_INFO                 DATE
LOCAL_ORDER_NO                    NUMBER
CHAIN_NO                          NUMBER
CSCN                              NUMBER
DSCN                              NUMBER
ENQ_TIME                          DATE
ENQ_UID                           NUMBER
ENQ_TID                           VARCHAR2(30)
DEQ_TIME                          DATE
DEQ_UID                           NUMBER
DEQ_TID                           VARCHAR2(30)
RETRY_COUNT                       NUMBER
EXCEPTION_QSCHEMA                 VARCHAR2(30)
EXCEPTION_QUEUE                   VARCHAR2(30)
STEP_NO                           NUMBER
RECIPIENT_KEY                     NUMBER
DEQUEUE_MSGID                     RAW(16)
SENDER_NAME                       VARCHAR2(30)
SENDER_ADDRESS                    VARCHAR2(1024)
SENDER_PROTOCOL                   NUMBER
USER_DATA                         CYRIS.ALTAS

Esta estructura es la misma para todas las queue tablas, el único cambio sería en el campo USER_DATA, en el que se incluiría el tipo de Dato que hayamos asociado a la Cola. (En este caso CYRIS.ALTAS, donde CYRIS es el esquema sobre el que se va a apoyar la Cola.) Y en este campo, es donde se incluirían los datos que quisiéramos propagar por la Cola. 

3.- Creación de la Cola

Con las estructuras ya creadas, ahora hace falta crear y activar una cola para que sea gestionada (encole y desencole) automáticamente mediante las jobs de Oracle, a través de Procedures y Funciones creadas por el usuario.

Para la creación de la cola (Como para la creación de las tablas ) también se realiza mediante el paquete DBMS_AQADM utilizando el Procedure CREATE_QUEUE. En nuestro ejemplo, ejecutaríamos:



BEGIN
  dbms_aqadm.create_queue(
        queue_name=> 'altas_c',                -- Queue
        queue_table=> 'altas_t',               -- Queue table
        queue_type=> DBMS_AQADM.NORMAL_QUEUE   -- Tipo de Cola
       );
COMMIT;
END;
/

Una vez creada la cola, lo único que nos queda es arrancarla, a través del procedure DBMS_AQADM.START_QUEUE; de este modo:

BEGIN
   dbms_aqadm.start_queue('altas_c', TRUE, TRUE); -- permitir encolar y desencolar
COMMIT;
END;
/ 

4.- Procesos de Encolar-Desencolar

Ahora con el entorno montado de este modo, ya sólo nos queda implementar los procedures de Encolar-Desencolar para que sean utilizados por el aplicativo según sus necesidades. Estos procesos utilizarán los procedures ENQUEUE y DEQUEUE del paquete DBMS_AQ.

* Nota: Es importante tener en cuenta, que los usuarios que vayan a utilizar las colas, tengan permisos Ejecución sobre el paqute DBMS_AQ, y sobre los roles AQ_ADMINISTRATOR_ROLE y  AQ_USER_ROLE: 
GRANT EXECUTE ON dbms_aq TO user;
GRANT aq_administrator_role TO user;
GRANT aq_user_role TO user; 
En las versiones 11g, para la asignación de permisos hay que ejecutar el procedure GRANT_QUEUE_PRIVILEGE:  
BEGIN  DBMS_AQADM.GRANT_QUEUE_PRIVILEGE (   'ALL',           -- privilege   
   'altas_c',       -- queue_name  
   'Role_colasaq',  -- grantee     
   FALSE);          -- grant_option
END


Un ejemplo de la implementación de los procesos de Encolado y Desencolado podría ser:


     ENCOLAR

CREATE OR REPLACE PROCEDURE ENCOLA (datos in altas, cola in VARCHAR2) as
    enq_opt dbms_aq.enqueue_options_t;
    msg_opt dbms_aq.message_properties_t;
    msg_id raw(16);
begin
DBMS_AQ.ENQUEUE (cola,        --Queue_name
                 enq_opt,     --Opciones de la Cola,
                 msg_opt,     --Propiedades del mensaje,
                 datos,       --Datos de entrada.
                 msg_id);     --msgid OUT RAW);;
end;
/
show errors

    DESENCOLAR


CREATE OR REPLACE PROCEDURE DESENCOLA (datos out altas, cola in VARCHAR2) as
    deq_opt dbms_aq.dequeue_options_t;
    msg_opt dbms_aq.message_properties_t;
    msg_id raw(16);
begin
    DBMS_AQ.DEQUEUE (cola,     --Queue
                     deq_opt,  --Opciones de Desencolado
                     msg_opt,  --Propiedades de Mensaje
                     datos,    --Datos de salida
                     msg_id ); --msgid OUT RAW);;
end;
/
show errors

No hay comentarios: