Num ambiente multiusuário a probabilidade de dois usuários alterarem o mesmo registro de um cadastro, simultaneamente, é muito alta. Por esta razão faz-se necessário impedir o acesso de um deles.
O Framework da linha Microsiga Protheus possui a função Softlock para esta finalidade. Esta função deve ser utilizada para bloquear um determinado registro, em atualização, durante as operações de interface, conforme pode ser observado abaixo:
// SoftLockSample.prw
If SoftLock(cAlias)
RegToMemory(cAlias,.F.,lVirtual)
Define MsDialog ___oDlg Of oFather:oWnd From 0, 0 To 0, 0 Pixel STYLE nOR( WS_VISIBLE, WS_POPUP )
aPosEnch := {,,,}
oEnc01:= MsMGet():New( cAlias, nReg, nOpc, ,"CRA", STR0004, aAcho, aPosEnch ,aCpos,,,,cTudoOk,___oDlg ,,lVirtual,.F.,,,,,,,,cTela) //"Quantas alterações?"
oEnc01:oBox:align := CONTROL_ALIGN_ALLCLIENT
bEndDlg := {|lOk| If(lOk:=___oDlg:End(), nOpcA:=1, nOpcA:=3), lOk}
___oDlg:nWidth := aDim[4]-aDim[2]
Activate MsDialog ___oDlg On Init ( FaMyBar(___oDlg,{|| If(Obrigatorio(aGets, aTela) .And. Eval(bOk) .And. Eval(bOk2, nOpc), Eval(bEndDlg), (nOpcA:=3, .F.))},{|| nOpcA := 3, ___oDlg:End()}, aButtons), ___oDlg:Move(aDim[1], aDim[2], aDim[4]-aDim[2], aDim[3]-aDim[1]) )
(cAlias)->(MsGoTo(nReg))
If nOpcA == 1
Begin Transaction
RecLock(cAlias,.F.)
For nX := 1 TO FCount()
FieldPut(nX, M->&(EVAL(bCampo, nX)))
Next nX
If Type("aMemos") == "A"
For nX := 1 to Len(aMemos)
cVar := aMemos[nX][2]
cVar1:= aMemos[nX][1]
MSMM(&cVar1, TamSx3(aMemos[nX][2])[1], , &cVar, 1, , , cAlias, aMemos[nX][1], cAliasMemo)
Next nX
EndIf
End Transaction
EndIf
A função SoftLock garante que a interface somente seja montada para o primeiro usuário que fez a tentativa de atualização ou exclusão. Enquanto a transação não for abortada ou concluída, o registro permanecerá bloqueado para os demais. Note que apesar da função SoftLock realizar um bloqueio, o uso da função RecLock continua a ser necessário na transação.