A partir da release 12.1.2510, o DBAccess gerencia locks no Cloud, permitindo reentrância na mesma thread.
É recomendado que UnLockByName deve repetir exatamente os parâmetros de LockByName, incluindo Empresa e Filial; caso contrário, a liberação falha.
Dúvida
Como funcionam as funções LockByName e UnLockByName no ambiente Cloud a partir da release 12.1.2510?
Ambiente
Cross Segmento - TOTVS Backoffice (Linha Protheus) - ADVPL - A partir da versão 12.1.2510.
Solução
A partir da release 12.1.2510, o controle de concorrência e de semáforos para clientes Cloud deixou de ser gerenciado pelo License Server e passou a ser realizado diretamente pelo DBAccess.
Com essa atualização, o DBAccess passa a reconhecer a sessão atual conectada ao banco de dados, permitindo a reentrância. Ou seja, ao solicitar o mesmo lock várias vezes na mesma thread, o sistema permite a operação e retorna verdadeiro (.T.).
A falha ao derrubar o lock ocorre quando a assinatura da função de liberação diverge da assinatura de criação.
A função LockByName cria o semáforo validando Empresa e Filial quando os parâmetros lógicos correspondentes são informados exemplo:
LockByName(cFun, .T., .T.)).
Se na função UnLockByName esses parâmetros lógicos forem omitidos, o Protheus assume o comportamento padrão de validar apenas a Empresa (.T.) e não validar a Filial (.F.). Essa diferença de assinaturas faz com que o sistema não encontre o lock exato, falhando na liberação e retornando falso (.F.).
Adicionalmente, se for utilizado um operador de negação antes da função de lock que obteve sucesso exemplo:
!LockByName(...)// o retorno avaliado será .F., pois a negação de .T. é .F.
Passos para validação do Lock;
-
Verifique a chamada da função LockByName em seu código-fonte para identificar quais parâmetros lógicos de controle por Empresa e Filial foram passados.
-
Localize a chamada correspondente da função UnLockByName responsável por eliminar o semáforo.
-
Garanta que os parâmetros lógicos passados no UnLockByName sejam rigorosamente idênticos aos utilizados no LockByName.
-
Exemplo: se utilizou LockByName(cFun, .T., .T.), utilize obrigatoriamente UnLockByName(cFun, .T., .T.).
-
Exemplo: se utilizou LockByName(cFun, .T., .T.), utilize obrigatoriamente UnLockByName(cFun, .T., .T.).
-
Compile as alterações e execute a rotina novamente para confirmar a liberação com sucesso (.T.).
#include 'totvs.ch'
User Function Lock()
RpcsetEnv("T1", "D MG 01")
Local cFun:="testeLock"
If LockByName(cFun, .T., .T.)
conout("Lock True!")
else
conout("Lock False!")
ENDIF
IF MsgYesNo("Desbloquear?","Lock")
If UnLockByName(cFun, .T., .T.)
conout("UnLock True!")
else
conout("UnLock False!")
ENDIF
Endif
Return()
0 Comentários