COMO EVITAR DUPLICIDADE NA ID DA TABELA

SEBINVENTER 17/05/2022 14:00:49
#499864
Olá, minha tabela de Pedidos a chave primária não é auto numeração, quando o usuário pede pra gravar o pedido eu chamo uma função que vai numa tabela auxiliar e pega o ultimo valor e depois que pega esse valor incrementa +1 na coluna pra o próximo pedido que for ser gravado. Conforme abaixo:

Public Function glb_PegaNovoValor(strCadastro As String) As Long
On Error GoTo PegaErro

Dim rs As ADODB.Recordset
Dim intValor As Long

intValor = 0

Set rs = New ADODB.Recordset
rs.Open "SELECT * FROM tbGuiaCadastro WHERE NomeCadastro="" & strCadastro & """, cnGestao, adOpenDynamic, adLockPessimistic

intValor = rs("ValorNovo")

rs("ValorAtual") = rs("ValorNovo")
rs("ValorNovo") = rs("ValorNovo") + 1
rs.Update

rs.Close
Set rs = Nothing

glb_PegaNovoValor = intValor

Exit Function

PegaErro:
MsgBox "Ocorreu o erro " & Str(Err), 48, "glb_PegaNovoValor"
Exit Function
End Function


O problema é que começou do nada ter duplicidade da chave, ou seja, 2 usuarios tao gravando o mesmo numero. Teria uma forma mais segura pra fazer isso?

grato a todos

JABA 17/05/2022 14:22:09
#499865
Resposta escolhida
Está acontecendo problema de concorrencia no seu banco. Ou seja, a última ID está sendo lida ao mesmo tempo por usuários diferentes; assim na hora de gerar o incremento, ele vai se repetir. Deixe o próprio banco fazer isso pra voce para evitar dor de cabeças como essa.
SEBINVENTER 17/05/2022 14:29:15
#499866
Citação:

:
Está acontecendo problema de concorrencia no seu banco. Ou seja, a última ID está sendo lida ao mesmo tempo por usuários diferentes; assim na hora de gerar o incremento, ele vai se repetir. Deixe o próprio banco fazer isso pra voce para evitar dor de cabeças como essa.


Citação:

:
Está acontecendo problema de concorrencia no seu banco. Ou seja, a última ID está sendo lida ao mesmo tempo por usuários diferentes; assim na hora de gerar o incremento, ele vai se repetir. Deixe o próprio banco fazer isso pra voce para evitar dor de cabeças como essa.




Mas preciso dar sequencia da numeracao já existente, pq tem casos que eu vou precisar popular essa tabela inicial com os dados vindo de outro banco, ai tem q seguir a sequencia de onde parou. Digamos que implantei um banco zerado, e o cliente ja tem algum outro banco onde preciso migrar os dados e no banco antigo estiver a chave 1510, ai comeco a partir do 1511 e segue.

Outra coisa, o cnGestao, adOpenDynamic, adLockPessimistic não seria pra evitar essa concorrencia?

grato pela orientacao
KERPLUNK 17/05/2022 14:59:23
#499867
Tem duas opções:
1 - Inserir um registro de pedido já com o número e ao invés de fazer insert dos dados, faça um update no registro previamente inserido
2 - Não disponibilizar o número do pedido quando o usuário criar e só mostrar depois de gravado. Ao gravar, aí voce faz a consulta do número de pedido e insere

SEBINVENTER 17/05/2022 15:44:43
#499868
Citação:

:
Tem duas opções:
1 - Inserir um registro de pedido já com o número e ao invés de fazer insert dos dados, faça um update no registro previamente inserido
2 - Não disponibilizar o número do pedido quando o usuário criar e só mostrar depois de gravado. Ao gravar, aí voce faz a consulta do número de pedido e insere


Citação:

:
Tem duas opções:
1 - Inserir um registro de pedido já com o número e ao invés de fazer insert dos dados, faça um update no registro previamente inserido
2 - Não disponibilizar o número do pedido quando o usuário criar e só mostrar depois de gravado. Ao gravar, aí voce faz a consulta do número de pedido e insere



Eu to gerando exatamente quando grava, e nao sei como tao conseguindo gravar ao mesmo tempo, sao somente 3 maquinas. A estava pensando de inverter, gerar o codigo quando pedir um novo pedido. ai ja fica reservado esse numero, quando pedir pra gravar ai eu gravo no banco com o numero q ja foi gerado...mas ai teria outro problema pq se o usuario desistisse do pedido, aquele numero ia se perder.

ai o cara faz mil pedidos, durante o mes todinho, e so agora de ontem pra ca q comeca esse problema,, ai tome reclamacao.
JABA 17/05/2022 16:23:03
#499871
Dá para controlar a semente de incremento diretamente no seu banco, não precisa ter que zerar tudo. Para colocar como chave primária, voce vai ter que retirar as duplicatas; depois é só aplicar o autoincremento. Faça isso manualmente lá.
SEBINVENTER 18/05/2022 11:38:04
#499879
Citação:

:
Tem duas opções:
1 - Inserir um registro de pedido já com o número e ao invés de fazer insert dos dados, faça um update no registro previamente inserido
2 - Não disponibilizar o número do pedido quando o usuário criar e só mostrar depois de gravado. Ao gravar, aí voce faz a consulta do número de pedido e insere




Rapaz, ve que estranho, to debugando no banco de dados a coluna "ValorNovo" ta como valor de 43668, quando eu chamo a funcao que vai gerar o novo valor, que ele abre a tabela e pega justamente essa colunca o valor que ele ler é 43669, mas quando retorna, retorna o numero q ta no banco. Que fantasma é esse?


SEBINVENTER 18/05/2022 12:25:39
#499880
Ola, desvendei um problema aqui, eu faco 2 processos: 1. gravo o pedidos e depois os seus itens, acontece que tem um begintrans antes de gravar o pedidos e so dou o commit depois que grava os itens, nesse intervalo o update nao escrevia de fato no banco, entao acredito q devido alguma lentidao dava tempo de outro usuario pegar ainda o valor anterior e gerar a duplicidade. tive q remover o begintrans e to testando.

mesmo assim vou tentar fazer como o JABA disse tambem, deixar auto incremento. fazer uns testes pra ve se vai ta ok
valeu!
SEBINVENTER 18/05/2022 12:27:26
#499881
Ola, desvendei um problema aqui, eu faco 2 processos: 1. gravo o pedidos e depois os seus itens, acontece que tem um begintrans antes de gravar o pedidos e so dou o commit depois que grava os itens, nesse intervalo o update nao escrevia de fato no banco, entao acredito q devido alguma lentidao dava tempo de outro usuario pegar ainda o valor anterior e gerar a duplicidade. tive q remover o begintrans e to testando.

mesmo assim vou tentar fazer como o JABA disse tambem, deixar auto incremento. fazer uns testes pra ve se vai ta ok
valeu!
NILSONTRES 18/05/2022 13:16:27
#499882
Como é chave primaria, trate o erro caso receba de volta o erro por duplicidade, incremente +1 ao numero do registro, até que não ocorra mais o erro.
SEBINVENTER 19/05/2022 13:13:12
#499892
Citação:

:
Como é chave primaria, trate o erro caso receba de volta o erro por duplicidade, incremente +1 ao numero do registro, até que não ocorra mais o erro.



Valeu pela dica.
Tópico encerrado , respostas não são mais permitidas