O Custo Invisível do "Check Lock" sem Pausa
Quando precisamos de monitorizar se um determinado objeto ou tabela foi libertado pelo sistema, a tentação imediata é estruturar um loop infinito para validar o estado em tempo real. Contudo, a ausência de uma pausa estratégica cobra um preço elevadíssimo e invisível ao servidor. Trata-se do clássico problema de Busy Waiting (espera ativa).
🛑 Cenário A: Força Bruta (Estresse de CPU)
O programa tenta ler a tabela de locks (representada aqui genericamente pela tabela BSEG) o máximo de vezes que a CPU permitir.
- Comportamento: O código é executado à velocidade máxima permitida pelo processador, sem qualquer interrupção.
- Resultado: Milhares (ou milhões) de registos são lidos num curto intervalo de apenas 1 segundo.
- Impacto: O Work Process associado atinge os 100% de utilização da CPU, gerando gargalos severos para os demais utilizadores do ambiente.
⚠️ Nota de Impacto: O servidor consome recursos de forma crítica e desnecessária para tentar obter uma informação que, na esmagadora maioria das vezes, demora segundos ou minutos a mudar (como uma ação humana).
🌱 Cenário B: Uso Consciente do WAIT
Introduzimos uma folga controlada de apenas 0.1 segundos a cada nova iteração do ciclo de checagem.
- Comportamento: O programa faz a validação pontual do estado e entra em suspensão ("dorme") durante uma fração de segundo.
- Resultado: O volume de leitura cai drasticamente para aproximadamente 10 consultas por segundo.
- Impacto: Esta frequência é mais do que suficiente para detetar um desbloqueio (seja ele efetuado por um utilizador ou por um processo em background), garantindo consumo quase nulo de processamento.
💡 Vantagem de Arquitetura: Em ambientes SAP ABAP, o comando
WAIT UP TO X SECONDSliberta temporariamente o Work Process atual de volta para o Dispatcher. Isto permite que o servidor atenda outras requisições críticas enquanto este programa específico aguarda.
💻 Exemplo Prático para Teste (Relatório ABAP)
O código abaixo está pronto para ser testado e homologado através da transação SE38. O relatório serve para evidenciar a diferença monumental no volume de acessos à base de dados num intervalo fixo de 1 segundo:
REPORT z_check_lock_performance.
DATA: lv_start TYPE timestampl,
lv_now TYPE timestampl,
lv_count TYPE i,
lv_dummy_hkt TYPE bseg-hkont.
CONSTANTS: lc_duration TYPE i VALUE 1. " Tempo fixo do teste em segundos
" =====================================================================
" --- TESTE 1: SEM WAIT (FORÇA BRUTA) ---
" =====================================================================
lv_count = 0.
GET TIME STAMP FIELD lv_start.
WHILE 1 = 1.
" Simula o check de lock realizando um SELECT simples
SELECT SINGLE hkont FROM bseg INTO lv_dummy_hkt.
lv_count = lv_count + 1.
GET TIME STAMP FIELD lv_now.
IF cl_abap_tstmp=>subtract( tstmp1 = lv_now tstmp2 = lv_start ) >= lc_duration.
EXIT.
ENDIF.
ENDWHILE.
WRITE: / '--- TESTE SEM WAIT (1 SEGUNDO) ---',
/ 'Total de Selects realizados:', lv_count.
ULINE.
" =====================================================================
" --- TESTE 2: COM WAIT 0.1s (PERFORMANCE OTIMIZADA) ---
" =====================================================================
lv_count = 0.
GET TIME STAMP FIELD lv_start.
WHILE 1 = 1.
SELECT SINGLE hkont FROM bseg INTO lv_dummy_hkt.
lv_count = lv_count + 1.
" Liberta o Work Process temporariamente para o sistema respirar
WAIT UP TO '0.1' SECONDS.
GET TIME STAMP FIELD lv_now.
IF cl_abap_tstmp=>subtract( tstmp1 = lv_now tstmp2 = lv_start ) >= lc_duration.
EXIT.
ENDIF.
ENDWHILE.
WRITE: / '--- TESTE COM WAIT 0.1s (1 SEGUNDO) ---',
/ 'Total de Selects realizados:', lv_count.