Dicas ABAP

Published on March 12th, 2012 | by Daiane Medeiros

33

Processamento em Paralelo utilizando RFC Assíncrona

Demorou, mas chegou! Meu post inaugural no ABAP Zombie! Vou começar falando um pouco sobre processamento paralelo com RFC Assíncrona. Hein???

O processamento em paralelo (ou paralelismo) não é um conceito novo, mas é pouco utilizado para melhoria de performance. Por quê?
Em alguns casos podemos utilizar mais de uma sessão (ou task) disponível, mas geralmente utilizamos apenas uma delas. É como se uma transportadora contasse apenas com um caminhão para levar seus produtos, quando há uma frota inteira de caminhões que podem ser utilizados.
Não é só isso, a maioria dos sistemas conta com mais de um servidor de aplicação com uma série de sessões disponíveis. Então, o que estamos esperando?

Utilizar processamento paralelo ou não, eis a questão!

Neste post vou mostrar um exemplo prático utilizando RFC Assíncrona. Vamos tentar equilibrar o trabalho do programa com base no número de dados informados na tela de seleção e nas sessões disponíveis nos servidores de aplicação. Por último, vamos analisar o tempo de execução do programa e comparar a execução utilizando uma única sessão. Então, vamos lá!

Análise do Tempo de Execução

Única sessão:

Utilizando Processamento em Paralelo:

Através da transação SE30, podemos analisar o tempo de execução de cada programa. No meu exemplo, eu consegui uma melhoria de 18% do tempo que levou para executá-lo em uma única sessão.

Mas atenção!!!

  • Antes de começar a implementar, devemos nos certificar que o processamento em paralelo deve ser logicamente independente. Como assim? Explico: cada processo não pode depender de outros dados que estão sendo processados paralelamente, pois não temos como garantir que os dados serão processados em uma ordem específica.
  • O programa principal não pode mudar de sessão depois de chamar a RFC Assíncrona, ou seja, você não deve usar SUBMIT ou CALL TRANSACTION depois de usar CALL FUNCTION STARTING NEW TASK.
  • Não é recomendado utilizar COMMIT dentro da RFC Assíncrona, pois poderia entrar em conflito com a sessão em que o programa principal está sendo executado.

É isso aí zombies, espero que tenham gostado, até uma próxima! 😉

Share on FacebookTweet about this on TwitterShare on LinkedInShare on Google+Email this to someonePrint this page

Tags:


About the Author

Abapeira desde 2008, curte som underground, arte urbana, bobeiras geek, luta krav maga, fala gírias idosas e jura que é uma pessoa normal.



33 Responses to Processamento em Paralelo utilizando RFC Assíncrona

  1. Custodio says:

    Ou eu estou bebado, ou esta faltando um monte de codigo nesse post, nao?

  2. aEEE Dai,

    Parabéns, post Legal Estadual e Bonito (Acho que só a Dai vai entender)

    Curti muito, muito mesmo.

    Abs.

  3. Gabriel Tognoli says:

    Prezados,

    Gostei do post e o incrível é que estou estudando o uso de RFC para um possível desenvolvimento, mas acho que vocês não estão cumprindo com o prometido! Lembro de um post em que vocês comentam que estão abolindo o uso de códigos procedurais.

    Cade o ABAP Objects? cadê as classes, os objetos, etc…??

    • Olá Gabriel!

      Na verdade, quem falou que ia deixar de programar de forma procedural fui eu, nesse post aqui! A idéia do ABAPZombie não é trocar todas as dicas que damos aqui para OO, cada um dos membros trabalha da maneira que achar melhor. Mas o Mauro e eu estamos preparando algumas coisas divertidas para as próximas semanas. Acho que você vai gostar 😀

      Abraços!

      • Gabriel Tognoli says:

        Maurico/Daiane,
        Meus amigos, obrigado pelo retorno!

        Comentei no intuito de desenvolvermos uma comunidade cada vez mais forte, deixando de lado velhos hábitos e rotinas, que fazíamos e que fazemos até hoje.

        Eu mesmo, sempre que penso em uma solução, me vem na cabeça o maldito procedural.

        Farei uma comparação com o inglês… Estudar no Brasil ou no exterior talvez não seja tão diferente, mas ao estar em outro país, nos vemos obrigados a entender e estudar, pq TUDO é inglês.

        Também estou adotando esta postura, mudar os meus códigos procedurais para OO. Confesso que ainda carrego comigo as velhas manias, acho até que vou recorrer a uma lobotomia! rs

      • Rodrigo says:

        Aee Mauricio… vc sabe minha opinião! heheh
        Eu odeio OO mas tudo bem… não programo mais mesmo!! heheh

    • Daiane Zigiotto says:

      Oi Gabriel! Obrigada pelo comentário! A ideia do post era somente mostrar o conceito de RFC Assíncrona, mas se você preferir, ao invés de usar CALL FUNCTION… PERFORMING (subrotina) você pode usar CALL FUNCTION… CALLING (método).
      Abraços!

  4. Antonio says:

    Cade a estrutura da Function Z_RFC_ASSINC?

    • Daiane Zigiotto says:

      Oi Antonio!
      A Z_RFC_ASSINC faz uma seleção na tabela BSEG utilizando como condição o valor do parâmetro de importação I_GJAHR e depois retorna os registros na tabela T_BSEG.
      Era essa sua dúvida?
      Abs,

      • Ahm, a Daiane explicou e tal, mas a estrutura da RFC não importa muito para o exemplo. Tanto faz quais são os parâmetros, o funcionamento do paralelismo, que é o importante do post, é o mesmo.

        Ah, e para quem não sabe: quando falamos “RFC”, estamos falando de uma função criada pela SE37/SE80 (e derivados do leite), mas que na primeira aba de características deve ter a opção “módulo de função remota” marcada.

  5. Bruno says:

    A ideia é muito boa, mas o exemplo foi muito mauzinho… As melhores situações para usar paralelismo são processos que usem principalmente capacidade de processamento, e não base de dados. Este exemplo feito com um programa de computação matemática tipo um algoritmo para calcular uma raíz quadrada ou algo desse género os resultados seriam muito melhores. 18% quase não justifica a perda de tempo a implementar o paralelismo.

    • Daiane Zigiotto says:

      Olá Bruno,
      A idéia do Paralelismo Assíncrono é dividir a carga do programa em pacotes e que os dados executados em paralelo sejam independentes entre si, e isso pode se aplicar a uma seleção de dados que usa uma tabela no FOR ALL ENTRIES com MUITOS registros, por exemplo, pois dessa forma você poderá melhorar (e muito) a performance do seu programa, e é justamente sobre isso que eu queria falar neste post…
      O seu exemplo pode ser aplicado no conceito de RFC Transacional (usando CALL FUNCTION… IN BACKGROUND TASK), pois é necessário chamar apenas um único processo separadamente. Infelizmente, no ambiente de testes que eu usei, existiam poucos registros então eu tive que me virar com o que eu tinha! 18% não parece ser muita coisa, mas isso varia de acordo com cada ambiente e com a quantidade de dados.
      Abs,

  6. Jesus says:

    Pô eu gostei. Tá simples e objetivo. O resto é só pesquisar, mas a base ta aqui.

  7. Deocleciano Maranhão Neto says:

    Gostei muito desse post, pois paralelismo é um assunto muito interessante em qualquer linguagem !!!
    Só fiquei triste pois o exemplo não mostra várias entradas para ilustrar melhor o paralelismo. Eu fiz alguns ajustes no código para tentar testar ao meu gosto 🙂
    ( A RFC deve ser feita em outro ambiente!)

  8. Deocleciano Maranhão Neto says:

    O código que enviei não ficou formatado … acho que não inseri a tag corretamente !!!!
    Será que ainda dá pra editar?
    (Deletar Comentário)

  9. Navier Stokes says:

    seguinte tive um dump depois de passar algumas vezes : segue o dump
    RPERF_ILLEGAL_STATEMENT
    TEXTO BREVE
    STATEMENT “CALL FUNCTION .. DESTINATION/STARTING NEW TASK /IN BACKGROUND TASK”

    SAPLOLEA

    The program was probably… Function modules called CONVERSION_EXIT_xxxxx_INPUT/OUTPUT or USER_EXIT_xxxxx_INPUT.

    etc etc etc .. alguém por favor me ajuda ?
    abracos

  10. Navier Stokes says:

    o ponto de cancelamento foi na funçao

    AC_FLUSH_CALL_INTERNAL”.

  11. Navier Stokes says:

    achei um lance no link http://help.sap.com/abapdocu_70/en/ABAPCALL_FUNCTION_STARTING.htm

    da um search em “…must not exceed certain threshold values. ”

    tem limite de diálogo nisso ?? Esse problema é disso ???

  12. Tatiana says:

    Olá, boa tarde!
    Tenho uma dúvida: é possível este processamento ser executado em background?
    Pelo que percebi, as seções são abertas “online” mesmo quando executo em background. Com isso, se for um processamento muito pesado, posso ter o risco de TIME OUT em alguma destas seções.

    • Olha, até onde eu sei essas novas tasks também são executadas em background… Particularmente, sempre otimizei programas massivos que são executados em background com paralelismo (starting new task) e nunca tive problemas.

      Abs!

  13. Tatiana says:

    Oi Mauricio, obrigada pelo retorno.
    Bom, hoje meu processamento está sendo executado em background sem cancelar. Porém tive que aumentar um pouco o número de seções a serem abertas. Pois com um número menor está dando TIME OUT.

    • Daiane Zigiotto says:

      Olá Tatiana, obrigada pelo seu comentário! Talvez o que pode te ajudar a definir a número de tasks é utilizando a função SPBT_INITIALIZE onde retorna a quantidade de tasks livres (FREE_PBT_WPS) e a quantidade máxima de tasks (MAX_PBT_WPS). Abs!

  14. Tatiana says:

    Olá Daiane, obrigada pelo retorno!
    Bom, já utilizamos este recurso.. 🙁
    De fato ajuda, mas não resolve o problema. A nossa questão aqui é o acesso a tabelas muito grandes, sem arquivamento.
    A outra idéia que surgiu foi disparar vários JOBs (pequenos JOBs, assim como é feita a chamada da CALL FUNCTION). O que estou tentando ver agora é como encadear as execuções posteriores. Tenho 5 processamentos encadeados, dentro do mesmo programa. O primeiro é que é problemático, e foi neste que trabalhamos o paralelismo. Os próximos 4 dependem da conclusão deste primeiro. Na solução com paralelismo, o tempode execução caiu de 2 horas para 20 min. Gostaria muito de continuar com este tempo… rsrsrsr…

  15. Daniel Jesus says:

    Mauricio, as funções ficam mesmo dialogo usando esta técnica. =/
    http://help.sap.com/saphelp_nw04/helpdata/EN/22/0425c6488911d189490000e829fbbd/content.htm

  16. Gilson says:

    Olá pessoal!

    Utilizei recentemente este exemplo no meu programa e tenho uma dúvida aqui… Quando o programa atinge todas as sessões ele cai no ELSE e decrementa 1 na variável v_task_ativa. Porém, volta para o início do Do e incrementa novamente e fica nesse Loop infinito por que só irá chamar o perform UPDATE_ORDER para subtrair a variável v_task_ativa quando sair do Loop. Isso é normal? Ou estou fazendo algo errado? :S

    Abs.

    • Daiane Zigiotto says:

      Oi Gilson! Desculpa a demora 🙁
      Muito bem observado, tinha um erro no código 😛
      Coloquei uma validação de sy-subrc, assim nos casos de erro, não incrementa o número de tasks, senão vira um loop infinito. Acho que fazendo isso já soluciona o problema.
      Vou arrumar o código no post, valeu pelo comentário!

      • Robson says:

        Segundo meu teste, se tiver menos tasks disponíveis que o número de incrementos do LOOP vai ficar em loop infinito, pois não vai ocorrer a chamada da FORM update_order para decrementar o números de tasks ativas. Pelo que estou observando, só vai chamar este FORM se encontrar um WAIT, faz sentido?
        Ex.:
        Número de tasks disponíveis: 2
        Número de anos a serem processados: 3
        Obrigado.

Leave a Reply

Your email address will not be published. Required fields are marked *

Back to Top ↑