Problema de Lock em Fila do Oracle via Dataserver

Discussão em 'Banco de Dados / Database' iniciado por heber@dmef.com.br, Novembro 24, 2011.

  1. heber@dmef.com.br

    heber@dmef.com.br Sem Pontuação

    Pessoal,
    Não sei se alguém tem familiaridade com Filas Oracle através do Dataserver.
    Meu problema é o seguinte:
    Eu acesso uma fila do ORACLE via RUN STORED PROC com um select * from table(cast(nome da fila)). Isso vai ser guardado num buffer via uma view criada para disparar essa query. Toda a vez que se faz um select nessa fila o resultado aparece no buffer. Dai dá para dar For Each no buffer como se fosse uma tabela PROGRESS.
    O processo é o seguinte:
    1. Executar o select;
    2. Ler o buffer;
    3. Consistir o registro;
    4. Criar uma api do Datasul com os dados da fila;
    5. Fazer o De-queue (outra stored proc que remove a fila).

    O problema é que podem ser disparados simultaneamente varios processos desses e algumas raras vezes entre o passo 1 e o passo 4 um outro processo entra e começa com o o mesmo registro fazendo com que seja processado duas vezes. Um clássico problema de LOCK.

    Como eu posso fazer o LOCK uma vez que não é uma tabela, mas uma Stored Procedure aliado a uma View oracle? Existe algum DO TRANSACTION que possa ser usada para locar a leitura do buffer ou da execução do SELECT?

    Abraço
  2. kirchner

    kirchner Membro Participativo Moderador

    Heber,

    Se você realmente utilizando um objeto tipo fila no Oracle, eu não tenho experiência.
    Mas nestes casos o SGBD controla a concorrência. O SQL Server, por exemplo, controla. Não sou expert Oracle, mas ele deve fazer isso também.

    Mas eu acredito que teus passos devam ser nesta linha:
    - abre transação
    - de-queue;
    - ler os dados que saíram da fila;
    - integra no EMS;
    - se estiver tudo OK commit, senão rollback.

    Você tem que ver como funciona as filas de Oracle. Ele garante entrega transacional, ordenada e uma única vez? Caso sim, os passos devem ser parecido com os acima. Se ele não garante, você tem que ver qual a técnica correta p/ trabalhar com isso.
  3. heber@dmef.com.br

    heber@dmef.com.br Sem Pontuação

    Valeu Marcos,
    Como seria esse comando no Progress?
    DO TRANSACTION ....?
    Como voce faz isso no SQL?
    Eu, por outro lado não sou muito fluente em Progress. Eu precisava de algo mais ou menos assim:

    DO TRANSACTION LOCK, ON ERROR UNDO.
    Passo 1
    Passo 2
    ...
    END.

    Tem algo assim?

    Obrigado pela ajuda

    Forte abraço
  4. kirchner

    kirchner Membro Participativo Moderador

    Quando eu falo em transação é no Oracle mesmo. Eu não sei te dizer os comandos.

    Esquece o Progress por um momento. Como você faria isso direto no Oracle?
    NO SQL Server é fácil:

    Código:
    BEGIN TRANSACTION
    RECEIVE FROM <minha fila> BLA BLA BLA;
    <processa os dados da forma adequada>;
    COMMIT;
    RECEIVE é o comando p/ de-queue no SQL Server.
    Sabendo os comandos que você precisa, é só jogar no SEND-SQL-STATEMENT lá no Progress...
  5. heber@dmef.com.br

    heber@dmef.com.br Sem Pontuação

    Excelente ideia.
    Vou testar.

Compartilhe esta Página