Erro de Key Violation
Tenho uma aplição em delphi com banco firebird usando os componente ib pra acesso... quando esta em rede se duas pessoas ao mesmo tempo mandar incluir um registro da um erro de ´Key Violation´ mesmo eu usando uma função pra pegar um novo código.
Alguem saberia como resolver eu problema?
Alguem saberia como resolver eu problema?
Daniel.felgar
Curtidas 0
Respostas
Rjun
08/04/2005
Tem certeza q essa funçao esta retornando códigos diferentes para as duas pessoas ?
GOSTEI 0
Silviogs
08/04/2005
Olá
vc poderia postar a função pra pegar um novo código.
Silvio Guedes
vc poderia postar a função pra pegar um novo código.
Silvio Guedes
GOSTEI 0
Ariovaldo
08/04/2005
Daniel conforme o Rjun já informou se vc realmente garante que sua função atribui valores diferente o problema pode estar no Componente Ibtransaction não esta configurado corretamente, Dê dois cliques neste componente vai aparecer uma janela com 3 radio buton seleciona o Radio do Meio não me lembro a descrição agora.
GOSTEI 0
Daniel.felgar
08/04/2005
Não.... mas em uma maquina só sempre retorna..... eu tenho o ´ssql´ de inclusão antes de ele executar o sql ele puxa o novo código....
GOSTEI 0
Daniel.felgar
08/04/2005
o componente já esta como read-comited...
GOSTEI 0
Rjun
08/04/2005
Em uma maquina ele so vai fazer uma requisição. Ai com certeza ele retorna um numero novo. Você ta usando trigger ? Senão, quando vc pega o novo codigo teria q salvar o codigo novo para que quando a outra maquina pedisse o novo codigo, ele teria o valor correto.
GOSTEI 0
Daniel.felgar
08/04/2005
Tipo eu num usu triger....mas logo após pegar o código ele salva seria tipo asism: novocodigo
salvana tabela
qyGeral.sql.clear;
qyGeral.sql.close;
qyGeral.sql.add(´Select max(´+nomecampo+´) as lastcode´);
qyGeral.sql.add(´from ´+nometabela);
qyGeral.Open;
if qyGeral.RecordCount = 0 then
result := 1
else
result := qyGeral.fieldbyname(´lastcode´).asinteger + 1;
salvana tabela
qyGeral.sql.clear;
qyGeral.sql.close;
qyGeral.sql.add(´Select max(´+nomecampo+´) as lastcode´);
qyGeral.sql.add(´from ´+nometabela);
qyGeral.Open;
if qyGeral.RecordCount = 0 then
result := 1
else
result := qyGeral.fieldbyname(´lastcode´).asinteger + 1;
GOSTEI 0
Rjun
08/04/2005
Nesse trecho voce esta so pegando o codigo. Não esta salvando. Então deve ser isso q esta acontecendo. Por que você não utiliza Stored Procedure ?
GOSTEI 0
Ariovaldo
08/04/2005
Neste Caso o Registro não esta fisico na tabela, ele só esta lógico portanto outra requisição solicitada não pegara o novo, seria interessante usar uma Trigger neste caso
GOSTEI 0
Daniel.felgar
08/04/2005
num esses trecho é so o do codigo.... depois q vem o ´insert into...´
num da pra usar.
num da pra usar.
GOSTEI 0
Daniel.felgar
08/04/2005
depois de executado o sql eu faço o
if trFB.InTransaction then
trFB.Commit;
if trFB.InTransaction then
trFB.Commit;
GOSTEI 0
Ariovaldo
08/04/2005
Quando vc da o Insert vc commita a Tabela? se não o registro só vai estar lógico lá, e o select não pega ele
GOSTEI 0
Ariovaldo
08/04/2005
Tenta mudar o Comando Para:
if trFB.InTransaction then
trFB.CommitRetaining;
if trFB.InTransaction then
trFB.CommitRetaining;
GOSTEI 0
Daniel.felgar
08/04/2005
qual a diferença entre os dois
GOSTEI 0
Ariovaldo
08/04/2005
Puts a Diferença eu não sei, mas tive um problema desses uma vez e só alterei isso, claro que existe uma propriedade no IBTransaction que vc seta ´TaCommit´ ou ´TaCommitRtaining´ muda para este segundo
GOSTEI 0
Silviogs
08/04/2005
Olá
Daniel geralmente num sistema em rede usa-se uma tabela aux para gerar os codigos, pq se vários usuários pedirem a mesma requisição vc não terá problemas com a sequência.
Ex: O segundo a pedir a req. só terá seu código quando o primeiro efutuar a rotina. De preferência use uma Stored Procedure, para garantir que a rotina de gerar um novo codigo seja executada no servidor.
Atenciosamente
Silvio Guedes
Daniel geralmente num sistema em rede usa-se uma tabela aux para gerar os codigos, pq se vários usuários pedirem a mesma requisição vc não terá problemas com a sequência.
Ex: O segundo a pedir a req. só terá seu código quando o primeiro efutuar a rotina. De preferência use uma Stored Procedure, para garantir que a rotina de gerar um novo codigo seja executada no servidor.
Atenciosamente
Silvio Guedes
GOSTEI 0
Daniel.felgar
08/04/2005
Tipo se eu estiver com a transação aberta ele não pode abrir outra ou pode?
GOSTEI 0
Gandalf.nho
08/04/2005
Use generators para garantir que os números sejam realmente únicos
GOSTEI 0
Silviogs
08/04/2005
Olá
geralmente neste caso usamos uma tabela auxiliar para gerar codigos automaticamente. Quando vários usuários pedem uma requisição para criar um novo registro, o segundo em diante só poderá receber um novo código quando o primeiro efetuar a rotina que deve ser uma Stored Procedure que está no servidor. Desta forma não haverá Key Violation.
Atenciosamente
Silvio Guedes
geralmente neste caso usamos uma tabela auxiliar para gerar codigos automaticamente. Quando vários usuários pedem uma requisição para criar um novo registro, o segundo em diante só poderá receber um novo código quando o primeiro efetuar a rotina que deve ser uma Stored Procedure que está no servidor. Desta forma não haverá Key Violation.
Atenciosamente
Silvio Guedes
GOSTEI 0
Silviogs
08/04/2005
Olá
desculpe a redundância pois pensei que não havia postado a resposta anterior.
Silvio Guedes
desculpe a redundância pois pensei que não havia postado a resposta anterior.
Silvio Guedes
GOSTEI 0