Locação de registros
Olá, amigos!!
Existe um controle de locação de registros no Interbase??
Vou citar um exemplo:
A atualização do mesmo registro em dois ou mais terminais.
Obrigado!!
Existe um controle de locação de registros no Interbase??
Vou citar um exemplo:
A atualização do mesmo registro em dois ou mais terminais.
Obrigado!!
Janderson
Curtidas 0
Respostas
Anonymous
03/02/2003
Infelizmente não há nenhum tipo de look de registro nem no interbase, nem no oracle e o sql server, por incrivel que pareça
Isso tem que se tratar via programação.
Para resolver isso, criei um flag na tabela 0 para não liverado e 1 para liberado.
Não é o jeito mais correto, mas, pelo menos funciona.
PS: O interbase trabalha com controle de concorrencia otimista, ou seja, aceita o ultimo comando que o usuario executou.
Rodrigo
Isso tem que se tratar via programação.
Para resolver isso, criei um flag na tabela 0 para não liverado e 1 para liberado.
Não é o jeito mais correto, mas, pelo menos funciona.
PS: O interbase trabalha com controle de concorrencia otimista, ou seja, aceita o ultimo comando que o usuario executou.
Rodrigo
GOSTEI 0
Marcos Fernando
03/02/2003
galera eu também precisa travar minha tabela quando o usuário estiver alterando só que não gostei da alteranativa e usar um flag na tabela magina se vc alterar e colocar na tabela 1 ai vc perde a comunicação vai ficar salva na tabela e ai como posso voltar a alterar depois..
Alguém tem alguma forma que funcione 100¬
Thanks
Alguém tem alguma forma que funcione 100¬
Thanks
GOSTEI 0
Vinicius2k
03/02/2003
Colega,
Esta informação de que não há Lock de registro no IB/FB está equivocada.
Basta executar o select com a opção de bloqueio e o registro estará ´lockado´ até o commit ou rollback da transação. O código abaixo é específico para o FB, mas existem ´truques´ para que isto possa ser feito no IB.
Algumas referências no fórum sobre isso:
http://forum.clubedelphi.net/viewtopic.php?t=52818
http://forum.clubedelphi.net/viewtopic.php?t=42455
http://forum.clubedelphi.net/viewtopic.php?t=41375
http://forum.clubedelphi.net/viewtopic.php?t=38276
http://forum.clubedelphi.net/viewtopic.php?t=21844
T+
Esta informação de que não há Lock de registro no IB/FB está equivocada.
Basta executar o select com a opção de bloqueio e o registro estará ´lockado´ até o commit ou rollback da transação. O código abaixo é específico para o FB, mas existem ´truques´ para que isto possa ser feito no IB.
select <CAMPOS> from <TABELA> where <CAMPO> = :parametro for update with lock
Algumas referências no fórum sobre isso:
http://forum.clubedelphi.net/viewtopic.php?t=52818
http://forum.clubedelphi.net/viewtopic.php?t=42455
http://forum.clubedelphi.net/viewtopic.php?t=41375
http://forum.clubedelphi.net/viewtopic.php?t=38276
http://forum.clubedelphi.net/viewtopic.php?t=21844
T+
GOSTEI 0
Marcos Fernando
03/02/2003
Grato amigo consegui bloquear na batata, agora como posso verificar se a tabela está bloqueada quando o usuário clica em alterar ao invés de gravar,
pois eu travo o registro em uma estação e a outra edita muda as informações e só dá a msg de travamento quando ele for gravar fazendo com que ele perca o tempo, gostaria que ao dar um edit já o informe
posso fazer isso via SP?
pois eu travo o registro em uma estação e a outra edita muda as informações e só dá a msg de travamento quando ele for gravar fazendo com que ele perca o tempo, gostaria que ao dar um edit já o informe
posso fazer isso via SP?
GOSTEI 0
Afarias
03/02/2003
faça um edit/post simulando uma alteração assim vc saberá se está travado, e se não estiver vc automaticamente terá travado o registro, ex:
T+
procedure FormCadastro.BotaoEditClick(Sender: TObject); begin with IBDataSet1 do begin try Edit; FieldByName(´campo´).AsString := FieldByName(´campo´).AsString; Post; // testa se está travado, se nào trava Edit; // coloca em edição se não estiver travado except <registro deve estar bloqueado> // mensagem do usuário end; end; end;
T+
GOSTEI 0
Marcos Fernando
03/02/2003
Seguinte eu tenho um um ClientDataSet ligado a um DataSetProvider que é ligado a uma Ibquery todos na mesma transação,
conforme o campo ´indice´ do ClientDataSet eu executo um select que me retorna aos dados completos em um IBDataSet que também está na mesma transação...
Ok tá tudo vindo certo, to gravando e inserindo BLZ, só que quando eu preciso efetuar o look o IBDataSet não me traz nenhuma informação:
faço assim no modo que funciona:
[color=green:a362634aba]IBDataSet.SelectSQL.Text := ´SELECT INDICE, NOMERAZAO, FANTASIA, especie FROM FORNECEDORES where indice =:indice ORDER BY NOMERAZAO´;[/color:a362634aba]
e se eu adcionar o travamento ´for update WITH LOCK´´ no final não vem da:
[color=red:a362634aba]IBDataSet.SelectSQL.Text := ´SELECT INDICE, NOMERAZAO, FANTASIA, especie FROM FORNECEDORES where indice =:indice ORDER BY NOMERAZAO for update WITH LOCK´;[/color:a362634aba]
Ok pode ser?
To perdendo um tempão pra acertar meu sistema..hehe
conforme o campo ´indice´ do ClientDataSet eu executo um select que me retorna aos dados completos em um IBDataSet que também está na mesma transação...
Ok tá tudo vindo certo, to gravando e inserindo BLZ, só que quando eu preciso efetuar o look o IBDataSet não me traz nenhuma informação:
faço assim no modo que funciona:
[color=green:a362634aba]IBDataSet.SelectSQL.Text := ´SELECT INDICE, NOMERAZAO, FANTASIA, especie FROM FORNECEDORES where indice =:indice ORDER BY NOMERAZAO´;[/color:a362634aba]
e se eu adcionar o travamento ´for update WITH LOCK´´ no final não vem da:
[color=red:a362634aba]IBDataSet.SelectSQL.Text := ´SELECT INDICE, NOMERAZAO, FANTASIA, especie FROM FORNECEDORES where indice =:indice ORDER BY NOMERAZAO for update WITH LOCK´;[/color:a362634aba]
Ok pode ser?
To perdendo um tempão pra acertar meu sistema..hehe
GOSTEI 0
Afarias
03/02/2003
|quando eu preciso efetuar o look o IBDataSet não me traz nenhuma
|informação:
traduzindo???
T+
|informação:
traduzindo???
T+
GOSTEI 0
Marcos Fernando
03/02/2003
se eu abrir o IBDataSet com o txt assim:
[color=green:d39ad8d523]´SELECT INDICE, NOMERAZAO, FANTASIA, especie FROM FORNECEDORES where indice =:indice ORDER BY NOMERAZAO´; [/color:d39ad8d523]ele me retorna as informações corretas:
NOMERAZAO | FANTASIA | especie
Marcos | Brasil | Fornecedor
e seu eu efetuar o look adicionando ´for update WITH LOCK´ no final da mesma ele não me retorna nada.
assim:
´SELECT INDICE, NOMERAZAO, FANTASIA, especie FROM [color=red:d39ad8d523]FORNECEDORES where indice =:indice ORDER BY NOMERAZAO for update WITH LOCK´;[/color:d39ad8d523]
Cruel
[color=green:d39ad8d523]´SELECT INDICE, NOMERAZAO, FANTASIA, especie FROM FORNECEDORES where indice =:indice ORDER BY NOMERAZAO´; [/color:d39ad8d523]ele me retorna as informações corretas:
NOMERAZAO | FANTASIA | especie
Marcos | Brasil | Fornecedor
e seu eu efetuar o look adicionando ´for update WITH LOCK´ no final da mesma ele não me retorna nada.
assim:
´SELECT INDICE, NOMERAZAO, FANTASIA, especie FROM [color=red:d39ad8d523]FORNECEDORES where indice =:indice ORDER BY NOMERAZAO for update WITH LOCK´;[/color:d39ad8d523]
Cruel
GOSTEI 0
Afarias
03/02/2003
e o banco é??? nenhuma mensagem de erro?!!?
bom, teste sem o FOR UPDATE (use apenas o WITH LOCK) ou tente dar um FetchALL após abrir o DataSet (se estiver usando o FOR UPDATE).
Não sei se há algum efeito negativo em usar tais recursos com o IBX já q este é apenas para IB.
T+
bom, teste sem o FOR UPDATE (use apenas o WITH LOCK) ou tente dar um FetchALL após abrir o DataSet (se estiver usando o FOR UPDATE).
Não sei se há algum efeito negativo em usar tais recursos com o IBX já q este é apenas para IB.
T+
GOSTEI 0
Marcos Fernando
03/02/2003
uffaaa
Grato deu certo usei somente WITH LOCK
tanks
Grato deu certo usei somente WITH LOCK
tanks
GOSTEI 0
Afarias
03/02/2003
o WITH LOCK (sem o FOR UPDATE) é justamente para ser usado nas consultas que trazem apenas 1 registro (consultas na chave primária por exemplo)
Com o FOR UPDATE (múltiplos registros) o LOCK é dado a cada registro após o FETCH (pra não sair bloqueando tudo...)
:D
T+
Com o FOR UPDATE (múltiplos registros) o LOCK é dado a cada registro após o FETCH (pra não sair bloqueando tudo...)
:D
T+
GOSTEI 0
Diogoalles
03/02/2003
bom dia pessoal,
Achei muito interessante esse tópico e gostaria de uma idéia sugestão de vocês baseado no que li nele.
Tenho uma View de banco (utilizo D7, FB1.5 e Mdo) e no meu form um componente MDOQuery que realiza o select na view com os devidos paramentros, retornando alguns registros.
O usuario pode alterar os dados de um desses registros retornados. Tenho uma trigger Update para essa view.
A alteração faço da seguinte maneira:
- o DBGrid contem os dados da MDOQuery que exibe vários registros.
- o usuario clica em Alterar e então é aberta uma tela que traz os campos ligados a um MDODataSet que também possui o select em cima da VIEW, mas retornado só o registro selecionado na outra tela para edição.
- Qual seria a maneira correta de utilizar o FOR UPDATE (ou uso só o WITH LOCK)?
- Utilizo essa opção tanto na MDOQuery que traz vários resultados ou somente no MDODataSet que traz só um registro para edição?
- Gostaria que no grid se o registro já estiver Lock eu pudesse exibir uma mensagem. Como seria?
obrigado
Diogo
Achei muito interessante esse tópico e gostaria de uma idéia sugestão de vocês baseado no que li nele.
Tenho uma View de banco (utilizo D7, FB1.5 e Mdo) e no meu form um componente MDOQuery que realiza o select na view com os devidos paramentros, retornando alguns registros.
O usuario pode alterar os dados de um desses registros retornados. Tenho uma trigger Update para essa view.
A alteração faço da seguinte maneira:
- o DBGrid contem os dados da MDOQuery que exibe vários registros.
- o usuario clica em Alterar e então é aberta uma tela que traz os campos ligados a um MDODataSet que também possui o select em cima da VIEW, mas retornado só o registro selecionado na outra tela para edição.
- Qual seria a maneira correta de utilizar o FOR UPDATE (ou uso só o WITH LOCK)?
- Utilizo essa opção tanto na MDOQuery que traz vários resultados ou somente no MDODataSet que traz só um registro para edição?
- Gostaria que no grid se o registro já estiver Lock eu pudesse exibir uma mensagem. Como seria?
obrigado
Diogo
GOSTEI 0
Afarias
03/02/2003
|- Qual seria a maneira correta de utilizar o FOR UPDATE (ou uso só o
|WITH LOCK)?
esse é um recurso de última instância q deve ser usado apenas em casos específicos, Não é algo pra se aplicar assim sem necessidade.
|- Utilizo essa opção tanto na MDOQuery que traz vários resultados ou
|somente no MDODataSet que traz só um registro para edição?
em nenhuma a não ser q vc saiba exatamente o q está fazando e tenha um motivo muito bom para usar esse tipo de recurso
|- Gostaria que no grid se o registro já estiver Lock eu pudesse exibir
|uma mensagem. Como seria?
faça o EDIT/POST dentro de um bloco try..except e capture a exceção informando do ´travamento´
T+
|WITH LOCK)?
esse é um recurso de última instância q deve ser usado apenas em casos específicos, Não é algo pra se aplicar assim sem necessidade.
|- Utilizo essa opção tanto na MDOQuery que traz vários resultados ou
|somente no MDODataSet que traz só um registro para edição?
em nenhuma a não ser q vc saiba exatamente o q está fazando e tenha um motivo muito bom para usar esse tipo de recurso
|- Gostaria que no grid se o registro já estiver Lock eu pudesse exibir
|uma mensagem. Como seria?
faça o EDIT/POST dentro de um bloco try..except e capture a exceção informando do ´travamento´
T+
GOSTEI 0
Diogoalles
03/02/2003
olá aFarias e pessoal
realmente vou ter que utilizar o lock, gostaria de saber qual a maneira mais correta, baseado na minha necessidade abaixo:
- Qual seria a maneira correta de utilizar o FOR UPDATE (ou uso só o WITH LOCK)?
- Utilizo essa opção tanto na MDOQuery que traz vários resultados ou somente no MDODataSet que traz só um registro para edição?
Tenho um sistema de agenda, onde vários micros podem estar acessando os dados trazidos por uma view.
Quando um dos usuarios selecionar um registro, será aberta uma tela para a edição do registro. Nessa nova tela é exibido através de Dataset o select também em cima da view, só que retornando só o registro selecionado na tela anterior.
Enquanto esse usuario estiver com esse registro nessa tela de edição não posso permitir que nenhum outro micro selecione-o.
por isso minhas duvidas acima
obrigado
Diogo
realmente vou ter que utilizar o lock, gostaria de saber qual a maneira mais correta, baseado na minha necessidade abaixo:
- Qual seria a maneira correta de utilizar o FOR UPDATE (ou uso só o WITH LOCK)?
- Utilizo essa opção tanto na MDOQuery que traz vários resultados ou somente no MDODataSet que traz só um registro para edição?
Tenho um sistema de agenda, onde vários micros podem estar acessando os dados trazidos por uma view.
Quando um dos usuarios selecionar um registro, será aberta uma tela para a edição do registro. Nessa nova tela é exibido através de Dataset o select também em cima da view, só que retornando só o registro selecionado na tela anterior.
Enquanto esse usuario estiver com esse registro nessa tela de edição não posso permitir que nenhum outro micro selecione-o.
por isso minhas duvidas acima
obrigado
Diogo
GOSTEI 0
Afarias
03/02/2003
| Qual seria a maneira correta de utilizar o FOR UPDATE (ou uso só o
|WITH LOCK)?
como é apenas 1 registro, só WITH LOCK
|- Utilizo essa opção tanto na MDOQuery que traz vários resultados ou
|somente no MDODataSet que traz só um registro para edição?
veja, se usar na que traz os resultados vc tem q usar FOR UPDATE, e, vai estar travando todo mundo de alterar algo só pq 1 usuário está vendo os registros
|Enquanto esse usuario estiver com esse registro nessa tela de edição
|não posso permitir que nenhum outro micro selecione-o.
então, só no q traz o registro pra edição
T+
|WITH LOCK)?
como é apenas 1 registro, só WITH LOCK
|- Utilizo essa opção tanto na MDOQuery que traz vários resultados ou
|somente no MDODataSet que traz só um registro para edição?
veja, se usar na que traz os resultados vc tem q usar FOR UPDATE, e, vai estar travando todo mundo de alterar algo só pq 1 usuário está vendo os registros
|Enquanto esse usuario estiver com esse registro nessa tela de edição
|não posso permitir que nenhum outro micro selecione-o.
então, só no q traz o registro pra edição
T+
GOSTEI 0
Diogoalles
03/02/2003
blz.. show de bola..
só mais duas questões:
no meu MDODataset utilizo o SelectSQL e o ModifySQL, tudo sobre minha view. Para o modify tenho uma treigger before update.
no SelectSQL meu codigo será: ´select * from view where codigo = :codigo with lock´ correto né? no momento que eu der um open no MDODataset o registro já estara bloqueado ?
como faço para liberar o registro ?
obrigado mais uma vez
abraço
Diogo
só mais duas questões:
no meu MDODataset utilizo o SelectSQL e o ModifySQL, tudo sobre minha view. Para o modify tenho uma treigger before update.
no SelectSQL meu codigo será: ´select * from view where codigo = :codigo with lock´ correto né? no momento que eu der um open no MDODataset o registro já estara bloqueado ?
como faço para liberar o registro ?
obrigado mais uma vez
abraço
Diogo
GOSTEI 0
Afarias
03/02/2003
|no SelectSQL meu codigo será: ´select * from view where codigo
|= :codigo with lock´ correto né?
WITH LOCK não é aplicado a VIEWS (ou pelo menos views com mais de 1 tabela) -- vc tem q usar em uma tabela apenas, sem JOIN ou subquerys.
|no momento que eu der um open no MDODataset o registro já estara
|bloqueado ?
sim
|como faço para liberar o registro ?
encerrando a transação! (commit ou rollback)
lembrando q isso é uma forma de bloqueio EXPLÍCITA, q geralmente é desnecessária visto q uma vês q o usuário comfirme a alteração (UPDATE) o registro fica automaticamente bloqueado até o fim da transação.
T+
|= :codigo with lock´ correto né?
WITH LOCK não é aplicado a VIEWS (ou pelo menos views com mais de 1 tabela) -- vc tem q usar em uma tabela apenas, sem JOIN ou subquerys.
|no momento que eu der um open no MDODataset o registro já estara
|bloqueado ?
sim
|como faço para liberar o registro ?
encerrando a transação! (commit ou rollback)
lembrando q isso é uma forma de bloqueio EXPLÍCITA, q geralmente é desnecessária visto q uma vês q o usuário comfirme a alteração (UPDATE) o registro fica automaticamente bloqueado até o fim da transação.
T+
GOSTEI 0
Afarias
03/02/2003
|WITH LOCK não é aplicado a VIEWS (ou pelo menos views com mais de
|1 tabela)
sendo mais exato: *NENHUMA* VIEW, ou TABELA EXTERNA ou PROCEDIMENTO SELECIONÁVEL
T+
|1 tabela)
sendo mais exato: *NENHUMA* VIEW, ou TABELA EXTERNA ou PROCEDIMENTO SELECIONÁVEL
T+
GOSTEI 0
Marcos Fernando
03/02/2003
galera estou com um erro enorme nas mão, uso IBX com a transação configurada assim:
e na base Fb eu tenho uma tringger no before onde eu verifico o iten que está sendo incluido e vou no cadastro e adiciono a entrada, tudo certo o problema que eu uso dar um commit somente após ter lançado a nota toda e enquanto isso se eu estiver dando entrada em um item e outro usuário tiver que dar saída do mesmo item ele não vai conseguir pois o registro vai estar travado por minha transação,,,
Como configuro a transação que vários usuarios consigaum editar gravar e não dar erro, ?
Ps esse gravar que falo não é gravar e depois commitar, somente gravar pois depois tenho o recurso de cancelar a transação...
thanks
read_committed rec_version nowait
e na base Fb eu tenho uma tringger no before onde eu verifico o iten que está sendo incluido e vou no cadastro e adiciono a entrada, tudo certo o problema que eu uso dar um commit somente após ter lançado a nota toda e enquanto isso se eu estiver dando entrada em um item e outro usuário tiver que dar saída do mesmo item ele não vai conseguir pois o registro vai estar travado por minha transação,,,
Como configuro a transação que vários usuarios consigaum editar gravar e não dar erro, ?
Ps esse gravar que falo não é gravar e depois commitar, somente gravar pois depois tenho o recurso de cancelar a transação...
thanks
GOSTEI 0