4D v16.3

Record Locking

Página Inicial

 
4D v16.3
Record Locking

Record Locking  


 

 

4D e 4D Server administram automaticamente os banco de dados evitando conflitos entre processos ou entre usuários. Dois usuários ou dois processos não podem modificar o mesmo registro ou objeto ao mesmo tempo. Entretanto, o segundo usuário ou processo pode acessar simultaneamente ao registro em modo apenas leitura.

Há muitas razões para utilizar os comandos multi-usuário:

  • Modificação de registros por programação.
  • Utilização de uma interface de usuário personalizada para operações multi-usuário.
  • Armazenamento de modificações relacionadas com uma transação.
Há três conceitos importantes a serem considerados quando se utilizam comandos em um banco de dados multi-processo:
  • Em um processo, cada tabela está em modo só leitura ou leitura/escrita.
  • Os registros são bloqueados quando são carregados e se desbloqueiam quando são descarregados.
  • Um registro bloqueado não pode ser modificado.

Nas seguintes seções, como convenção, a pessoa que realiza uma operação no banco de dados multi-usuários é o usuário local. As outras pessoas que otimizam o banco de dados são os outros usuários. A discussão é desde o ponto de vista do usuário local. Da mesma forma, desde o ponto de vista multi-processo, o processo executando uma operação no banco de dados é o processo atual. Qualquer outro processo em curso de execução é referenciado como sendo outro processo. A discussão é desde o ponto de vista do processo atual.

Um registro bloqueado não pode ser modificado pelo usuário local ou o processo atual. Um registro bloqueado pode ser carregado, mas não modificado. Um registro é bloqueado quando um dos outros usuários ou processos carrega o registro para realizar uma modificação ou quando o registro está empilhado. Apenas o usuário que modifica o registro vê o registro como desbloqueado. Todos os outros usuários e processos vem o registro como bloqueado e portanto não disponível para modificação. Uma tabela deve estar em modo leitura/escrita para que um registro seja carregado como desbloqueado.

Cada tabela de um banco de dados está em modo leitura/escrita ou em modo só leitura para cada usuário e processo do banco de dados. Apenas leitura significa que os registros da tabela podem ser carregados mas não modificados. Leitura/escrita significa que os registros da tabela podem ser carregados e modificados se nenhum outro usuário/processo tenha bloqueado o registro previamente.

Note que se muda o estado de uma tabela, a mudança é realizada para o próximo registro carregado. Se já houver um registro carregado quando muda o estado da tabela, o registro não é afetado pela mudança de estado.

Quando uma tabela está em modo só leitura e um registro é carregado, o registro está sempre bloqueado. Em outras palavras, o registro pode ser mostrado, impresso e utilizado, mas não modificado.

Note que o modo só leitura aplica unicamente a a edição de registros existentes. O estado só leitura não afeta a criação de novos registros. Pode agregar registros a uma tabela só leitura utilizando os comandos CREATE RECORD e ADD RECORD ou os comandos de menus do ambiente Desenho. Note que o comando ARRAY TO SELECTION não está afetado pelo estado só leitura já que permite criar e modificar registros.

4D define automaticamente uma tabela em modo só leitura para os comandos que não precisam de acesso de escrita aos registros. Estes comandos são: DISPLAY SELECTION, DISTINCT VALUES, EXPORT DIF, EXPORT SYLK, EXPORT TEXT, _o_GRAPH TABLE, PRINT SELECTION, PRINT LABEL, QR REPORT, SELECTION TO ARRAY, SELECTION RANGE TO ARRAY.

Pode saber em qualquer momento o estado de uma tabela utilizando a função Read only state.

Antes de executar qualquer desses comandos, 4D guarda o estado atual da tabela (só leitura ou leitura/escrita) para o processo atual. Depois de executar o comando, o estado inicial é restabelecido.

Quando uma tabela está em leitura/escrita e se carrega um registro, o registro estará desbloqueado se nenhum outro usuário tiver bloqueado o registro primeiro. Se o registro está bloqueado por outro usuário, o registro é carregado como um registro bloqueado que não pode ser modificado pelo usuário local.

Uma tabela deve estar em modo leitura/escrita e o registro carregado para que seja desbloqueada e portanto modificável.

Se um usuário carrega um registro de uma tabela em modo leitura/escrita, nenhum outro usuário pode carregar esse registro para modificação. Entretanto, outros usuários podem adicionar registros à tabela, seja através dos comandos CREATE RECORD e ADD RECORD ou manualmente, no ambiente Desenho.

O modo leitura/escrita é o estado padrão para todas as tabelas quando um banco de dados é aberto e se inicia um novo processo.

Pode utilizar os comandos READ ONLY e READ WRITE para mudar o estado de uma tabela. Se deseja mudar o estado de uma tabela para voltar um registro de apenas leitura ou leitura/escrita, pode executar o comando antes de carregar o registro. Todo registro já carregado não é afetado pelos comandos READ ONLY e READ WRITE

Cada processo tem seu próprio estado (só leitura ou leitura/escrita) para cada tabela no banco de dados.

Como padrão, se não usar o comando READ ONLY, todas as tabelas estão em modo leitura/escrita.

Para que o usuário local possa modificar um registro, a tabela deve estar em modo leitura/escrita e o registro deve ser carregado e desbloqueado.

Cada um dos comandos que carrega um registro atual (se houver um), tais como NEXT RECORD, QUERY, ORDER BY, RELATE ONE etc., define o registro como bloqueado ou desbloqueado. O registro se carrega em função do estado atual de sua tabela (apenas leitura ou leitura/escrita) e de sua disponibilidade. Um registro também pode ser carregado de uma tabela relacionada por um dos comandos que provoca uma relação automática.

Se uma tabela está em modo leitura unicamente, para um processo ou usuário, todo registro carregado desta tabela está bloqueado. Um registro bloqueado não pode sermodificado ou apagado pelo processo ou usuário. O modo apenas leitura é o modo recomendado para a visualização ou recuperação de dados, já que não proibe que outros usuários ou processos acessem os dados em modo leitura/escrita se necessário.

Se uma tabela está em modo leitura/escrita, todo registro carregado desta tabela está desbloqueado apenas se nenhum outro usuário tiver bloqueado o registro primeiro. Um registro desbloqueado pode ser modificado e guardado. Uma tabela deve ser colocada em modo leitura/escrita antes que um registro necessite ser carregado, modificado, e depois guardado.

Se o registro deve ser modificado, utilize a função (Locked para provar se o registro está bloqueado por outro usuário. Se um registro estiver bloqueado ((Locked devolve True), carregue o registro com o comando LOAD RECORD e teste novamente se o registro está bloqueado ou não. Esta sequência deve continuar até que o registro seja desbloqueado ((Locked devolve False).

Quando termine as modificações a um registro, o registro deve ser liberado (e portanto desbloqueado para os outros usuários) com UNLOAD RECORD. Se um registro não é liberado, ele permanecerá bloqueado para os outros usuários até que um novo registro atual seja selecionado. Mudar o registro atual de uma tabela desbloqueia automaticamente o registro atual anterior. Deve chamar explicitamente a UNLOAD RECORD se não mudar o registro atual. Este princípio aplica aos registros existentes. Quando um novo registro é criado, pode ser guardado sem importar o estado da tabela a qual pertence.

Nota: quando se utiliza em uma transação, o comando UNLOAD RECORD descarrega o registro atual só para o processo que administra a transação. Para os outros processos, o registro permanece bloqueado até que a transação não seja confirmada (ou cancelada).

Utilize o comando  LOCKED BY para ver que usuário e/ou processo bloqueou um registro.

Nota: uma boa prática é colocar todas as tabelas em modo de apenas leitura quando se inicia cada processo (utilizando a sintaxe READ ONLY(*)) abaixo, se põe cada tabela em modo leitura/escrita só quando seja necessário.O acesso às tabelas em modo de apenas leitura é mais rápido e poupa mais memória. Por outro lado, mudando o estado de uma tabela se otimiza em modo cliente/servidor, ja que não causa nenhum tráfego de rede adicional: a informação só se envia ao servidor quando for executado um comando que requeira um acesso adequado a tabela.

O seguinte exemplo mostra o loop mais simples para carregar um registro não bloqueado:

 READ WRITE([Clientes]) ` Define o estado da tabela em modo leitura/escritura
 Repeat ` Faz um loop até que o registro esteja desbloqueado
    LOAD RECORD([Clientes]) ` Carrega e bloqueia o estado
 Until(Not(Locked([Clientes])))
  ` Fazer algo para o registro aqui
 READ ONLY([Clientes]) ` Define o estado da tabela em modo só de leitura


O loop continua até que o registro seja desbloqueado.

Um loop como este se utiliza unicamente quando é pouco provável que o registro esteja bloqueado por outra pessoa, já que o usuário teria que esperar até que o loop termine. Este loop não se utiliza a menos que o registro só seja modificado por um método.

O seguinte exemplo utiliza o loop anterior para carregar um registro desbloqueado e modificar o registro:
 READ WRITE([Inventario])
 Repeat ` Loop até que o registro seja desbloqueado
    LOAD RECORD([Inventario]) ` Carregar o registro e bloqueá-lo
 Until(Not(Locked([Inventario])))
 [Inventory]Part Qty:=[Inventario]Part Qty-1 ` Modificar o registro
 SAVE RECORD([Inventario]) ` Guardar o registro
 UNLOAD RECORD([Inventario]) ` Permitir que os outros usuários o modifiquem
 READ ONLY([Inventario])


O comando MODIFY RECORD notifica automaticamente ao usuário se um registro estiver bloqueado e evita que o registro seja modificado. O seguinte exemplo evita esta notificação automática testando o registro primeiro com a função Locked. Se o registro estiver bloqueado, o usuário pode cancelar.

Este exemplo prova eficientemente se o registro atual está bloqueado para a tabela [Comandos]. Se estiver bloqueado, o processo é atrasado pelo método por um segundo. Esta técnica pode ser utilizada em um desenvolvimento multi-usuário ou multi-processo:
 Repeat
    READ ONLY([Comandos]) ` Não necessita leitura/escrita pelo momento
    QUERY([Comandos])
  ` Se a pesquisa terminou e o registros são devolvidos
    If((OK=1) & (Records in selection([Comandos])>0))
       READ WRITE([Comandos]) ` Coloque a tabela em modo leitura/escrita
       LOAD RECORD([Comandos])
       While(Locked([Comandos]) & (OK=1)) `Se o registro estiver bloqueado,
  ` loop até que o registro seja liberado
  ` Quem bloqueou o registro?
          LOCKED ATTRIBUTES([Comandos];$Processos;$Usuario;$Maquina;$Nome)
          If($Processo=-1) ` O registro foi apagado?
             ALERT("O registro foi apagado no intervalo.")
             OK:=0
          Else
             If($Usuario="") ` Está em modo mono-usuário?
                $Usuario:="você"
             End if
             CONFIRM("O registro está sendo utilizado por "+$Usuario+" no processo "+$Nome+" Processo.")
             If(OK=1) ` Se quer esperar alguns segundos
                DELAY PROCESS(Current process;120) ` Espere alguns segundos LOAD RECORD([Comandos])` Trate de carregar o registro
             End if
          End if
       End while
       If(OK=1) ` O registro está desbloqueado
          MODIFY RECORD([Comandos]) ` Pode modificar o registro
          UNLOAD RECORD([Comandos])
       End if
       READ ONLY([Comandos]) ` Voltar a modo apenas leitura
       OK:=1
    End if Until(OK=0)


Certos comandos da linguagem realizam ações particulares quando encontram um registro bloqueado.

Esta é a lista desses comandos e suas ações quando encontram um registro bloqueado.

  • Certos comandos da linguagem realizam ações particulares quando encontram um registro bloqueado.

    Esta é a lista desses comandos e suas ações quando encontram um registro bloqueado.

  • MODIFY RECORD : mostra uma caixa de diálogo indicando que o registro está em uso. O registro não é mostrado, portanto o usuário não pode modificá-lo. No ambiente Desenho, o registro é mostrado em estado apenas leitura.
  • MODIFY SELECTION: se comporta normalmente exceto quando o usuário faz duplo clique em um registro para modificá-lo. MODIFY SELECTION mostra uma caixa de diálogo indicando que o registro está em uso e depois permite o aceso ao registro em modo apenas leitura.
  • APPLY TO SELECTION: carrega um registro bloqueado, mas não o modifica. APPLY TO SELECTION pode ser utilizado para ler informação de uma tabela sem ter cuidados especiais. Se o comando encontra um registro bloqueado, o registro se coloca no conjunto sistema LockedSet.
  • DELETE SELECTION: não apaga os registros bloqueados; simplesmente os ignora. Se o comando encontra um registro bloqueado, o registro é colocado no conjunto sistema LockedSet.
  •  DELETE RECORD: este comando é ignorado se o registro está bloqueado. Não se devolve nenhum erro. Deve provar que o registro está desbloqueado antes de executar este comando.
  •  SAVE RECORD: este comando é ignorado se o registro está bloqueado. Não se devolve nenhum erro. Deve provar que o registro está desbloqueado antes de executar este comando.
  • ARRAY TO SELECTION: não guarda os registros bloqueados. Se o comando encontra um registro bloqueado, o registro é colocado no conjunto sistema LockedSet.
  • GOTO RECORD: em um banco de dados multi-usuários/multi-processos os registros podem ser adicionados ou apagados por outros usuários, portanto os números dos registros podem variar. Seja prudente quando referencie um registro diretamente, um registro por número em um banco de dados multi-usuários.
  • Conjuntos: seja especialmente cuidadoso com os conjuntos, já que a informação na que se baseia o conjunto pode ser modificada por outro usuário ou processo.



Ver também 

LOAD RECORD
Locked
LOCKED BY
Métodos
READ ONLY
Read only state
READ WRITE
UNLOAD RECORD
Variáveis

 
PROPRIEDADES 

Produto: 4D
Tema: Bloqueio de Registros

 
HISTÓRIA 

 
ARTICLE USAGE

Manual de linguagem 4D ( 4D v16)
Manual de linguagem 4D ( 4D v16.1)
Manual de linguagem 4D ( 4D v16.2)
Manual de linguagem 4D ( 4D v16.3)