Christian,
O padrão do Protheus é trabalhar com RecLock
, ao fazer um RecLock
, é efetuado o lock do registro no DBAccess ou a criação do registro via DBAccess, que também que faz o incremento do R_E_C_N_O_
de maneira correta.
Além disso, o RecLock
fica responsável pela gravação de logs e informações de lock, quando você tenta efetuar o lock de um registro e aparece aquela tela informando que o registro está em lock, com informações do usuário e rotina, o responsável por isso, também é o próprio RecLock
.
O RecLock
também tem o comportamento de retry, quando um registro está em lock, ele tenta pegar o registro de novo, ali aparece a dialog citada para abortar o processo, fazendo com que o RecLock
retorne false
.
Por fim, eu acho... O RecLock
tem o comportamento de evitar deadlock (abendlock) em REST/SOAP entre outros, quando a thread não tem interface e você tenta fazer o lock do registro, não existe interface para cancelar o processo, logo, é possível que fique em retry, por conta disso quando em REST/SOAP, o retry tem um tempo de vida, ao esgotar esse tempo a thread é encerrada com informações sobre a tentativa de lock.
Legal, talvez tenha até mais informações sobre o RecLock, mas no momento não lembro! :)
Recomendo a utilização do RecLock para evitar qualquer problema, ele facilita inclusive o rastreamento caso ocorra algum problema, gerando logs no DBAccess etc.
Agora quandt a usar comandos DML, como INSERT, UPDATE, DELETE.
Ao fazer um insert utilizando MAX(R_E_C_N_O_) + 1
, funciona? As vezes, existe a possibilidade de gerar erro de PK caso duas thread façam uma inserção ao mesmo tempo, afinal, antes do commit, o R_E_C_N_O_
será o mesmo para ambas.
Além disso, ao fazer uma inserção "na mão", o DBAccess acaba não sabendo sobre essa nova numeração de R_E_C_N_O_
, com isso, também existe a chance de gerar error.log de PK.
Normalmente, para situações como essa, você acaba tendo de atualizar a tabela no DBAccess utilizando TCRefresh
, que é uma função pesada, limpa todo o cache da tabela e refaz o mesmo.
Para delete e update, acredito que os riscos sejam menores, mas não deixam de existir, uma deleção física pode acarretar a situação complicada, como uma outra thread estar posicionada exatamente no registro deletado e estar fazendo uso do mesmo, diferente de uma deleção lógica (D_E_L_E_T_
), isso pode gerar até mesmo exceções.
Para uma grande quantidade de inserções, foi criada a classe FWBulk
, que utiliza de recursos do próprio DBAccess para efetuar a inserção em blocos, diminuindo o IO e aumentando muito a performance:
https://tdn.totvs.com/display/public/PROT/FWBulk