INACREDITÁVEL  XML
Índice dos Fóruns » Arquitetura de Sistemas
Autor Mensagem
skill_ufmt
JavaEvangelist
[Avatar]

Membro desde: 20/05/2003 18:02:23
Mensagens: 318
Localização: Cuiabá - MT
Offline

Galerinha,

Estou aqui quase saindo do trabalho, há 1 dia da entrega do sistema para o cliente, e a aplicação para de funcionar completamente.

Como perdigueiro sai desesperadamente atrás do problema, quando me deparo com a seguinte situação:

Tenho uma maldita tabela no BD rodando em ORACLE onde existe uma chave primáira composta, acontece que um dos campos dessa chave é sequêncial. EX.

Chave Composta
campo1 campo2
10 1
10 2
10 3
11 1
11 2
11 3

Essa tabela é a principal tabela do sistema.

Acontece que para o sequênciamento estava sendo feito um SELECT MAX no campo e somando 1

Agora imaginem, 3000 acessos silmultâneos fazendo este select + 1, e retornado o mesmo valor, visto que isso não garante um lock na tabela.

Oque ocorre, aplicação condenada

Surgiram algumas idéias, mas nada que resultasse numa solução viável ao momento, então resolvi recorrer a esse poço de talentos para que alguma alma me de alguma sugestão ou pelo um ombro amigo pra chorar

E para os que pensaram em trigger, e storeProcedures, definitivamente fora de questão por exigências do cliente.

O sistema incrivelmente já está em produção na sua versão 1(não imagino como) e este é uma versão dois deste mesmo sistema(meu pai eterno), portanto, sem mudanças radicais ou vai mais um boooom tempo de refactoring.

idéias?

This message was edited 1 time. Last update was at 19/04/2005 18:05:57


Windows: Not Plug & Play, but Bug & Pay!
_________________________________________________
Kivanio Pereira Barbosa
Bacharel em Ciência da Computação

CUIABÁ JAVA USERS
www.cajumt.com.br
[WWW] aim icon [MSN] [ICQ]
mister__m
Virtual Machine Man
[Avatar]

Membro desde: 18/03/2005 16:13:17
Mensagens: 736
Offline

Mudar o segundo valor pra ser sempre sequencial, independente do primeiro? Algo como:


Michael Nascimento Santos, aka Mister M

Summa Technologies do Brasil - http://www.summa-tech.com/
genesis: Uma nova forma de desenvolver aplicações - https://genesis.dev.java.net/
ThinNB: Suporte a Thinlet no NetBeans - https://thinnb.dev.java.net/
Líder da JSR-310 - Date and Time API
Expert Group Member das JSRs 207 (PD4J), 250 (Common Annotations), 270 (Java 2 SE 6.0), 296 (Swing Framework) e 303 (Bean Validation)
SouJava: Fortalecendo a comunidade Java brasileira - https://soujava.dev.java.net/ https://www.soujava.org.br/
JSR Community @ java.net - http://community.java.net/jsr
Blogs - http://blog.michaelnascimento.com.br/ http://today.java.net/pub/au/80
Twitter - @mr__m
[WWW]
thingol
Moderador

Membro desde: 29/07/2004 16:10:13
Mensagens: 17543
Offline

select max? Isso é coisa de quem nunca viu "SEQUENCEs" na vida e resolveu usar um banco de dados Oracle. Aproveitando o que o Mister__M lhe disse, daria para alimentar o segundo campo com uma sequence, ou então usar uma outra sequence para gerar um número sequencial, e calcular o primeiro e o segundo campo a partir desse número gerado?
[WWW]
skill_ufmt
JavaEvangelist
[Avatar]

Membro desde: 20/05/2003 18:02:23
Mensagens: 318
Localização: Cuiabá - MT
Offline

mister__m wrote:Mudar o segundo valor pra ser sempre sequencial, independente do primeiro? Algo como:



solução boa, mas acontece que são Pai e Filhos, nem semrpe vai ter essa sequência, por ex.

se eu pegar o 10 2, no seu exemplo ai, eu teria que gerar 10 7, 10 8, enfim alguns registros e não somente 1.

Outra coisa, é que esse registro só é gravado nesta tabela após ser feitas outras 3 operações no banco, e um comit no final de tudo isso.

Acontece que se der um rollback, é pau na coisa, se mais de um usuário acessar ao mesmo tempo, é pau na app, não posso dar lock na tabela, pois isso impediria os outros 2999 usuários de fazer operações nela

Uma sugestão foi ter uma segunda tabela auxiliar onde se repetissem estes dois valores e esta sim fosse lockada, mas mas isso implicaria em mudanças estruturais e boas partes da aplicação

Sem contar que a app, é totalmente estruturada, oo passo longe disso aqui, e não foi me permitido refazer tudo ou refatorar.

Windows: Not Plug & Play, but Bug & Pay!
_________________________________________________
Kivanio Pereira Barbosa
Bacharel em Ciência da Computação

CUIABÁ JAVA USERS
www.cajumt.com.br
[WWW] aim icon [MSN] [ICQ]
skill_ufmt
JavaEvangelist
[Avatar]

Membro desde: 20/05/2003 18:02:23
Mensagens: 318
Localização: Cuiabá - MT
Offline

thingol wrote:select max? Isso é coisa de quem nunca viu "SEQUENCEs" na vida e resolveu usar um banco de dados Oracle. Aproveitando o que o Mister__M lhe disse, daria para alimentar o segundo campo com uma sequence, ou então usar uma outra sequence para gerar um número sequencial, e calcular o primeiro e o segundo campo a partir desse número gerado?


Acontee que a SEQUENCE não funciona em chaves compostas

Tentamos simular um sequence, com uma tabela auxiliar, e usando um "for update" após o select, mas isso não ficou nada viável

Windows: Not Plug & Play, but Bug & Pay!
_________________________________________________
Kivanio Pereira Barbosa
Bacharel em Ciência da Computação

CUIABÁ JAVA USERS
www.cajumt.com.br
[WWW] aim icon [MSN] [ICQ]
thingol
Moderador

Membro desde: 29/07/2004 16:10:13
Mensagens: 17543
Offline

Pelo que estou imaginando, você poderia tentar fazer uma solução mista - obter o primeiro campo com uma SEQUENCE, e o segundo com SELECT MAX. Qual seria o problema nesse caso?
[WWW]
skill_ufmt
JavaEvangelist
[Avatar]

Membro desde: 20/05/2003 18:02:23
Mensagens: 318
Localização: Cuiabá - MT
Offline

thingol wrote:Pelo que estou imaginando, você poderia tentar fazer uma solução mista - obter o primeiro campo com uma SEQUENCE, e o segundo com SELECT MAX. Qual seria o problema nesse caso?


O primeiro campo é imutável a cada gerão de "Filhos", o que muda seria o segundo campo que é no caso o sequencial.

O problema do MAX, é que ele não me garante um valor exclusivo, e se mais uma pessoa tentar usar este mesmo valor, o ORACLE trava geral, e esse valor em questão fia inutilizável enquanto o oracle não comitar as operações pendentes, só que se alguém vai lá e faz MAX novamente me retorna o mesmo valor, porque não foi inserido nada lá entende? a da sinuca de bico, porque o MAX sempre me trás o cara que não ta comitado e inutilizável, deixando travado banco e aplicação.

Windows: Not Plug & Play, but Bug & Pay!
_________________________________________________
Kivanio Pereira Barbosa
Bacharel em Ciência da Computação

CUIABÁ JAVA USERS
www.cajumt.com.br
[WWW] aim icon [MSN] [ICQ]
mister__m
Virtual Machine Man
[Avatar]

Membro desde: 18/03/2005 16:13:17
Mensagens: 736
Offline

Eu nunca disse que ia ficar "bonitinho" assim

Mas, por que não pode ser 10 1, 11 2, 10 3? Pelo que eu entendi, o importante é não coincidir e manter a ordem, não?

Michael Nascimento Santos, aka Mister M

Summa Technologies do Brasil - http://www.summa-tech.com/
genesis: Uma nova forma de desenvolver aplicações - https://genesis.dev.java.net/
ThinNB: Suporte a Thinlet no NetBeans - https://thinnb.dev.java.net/
Líder da JSR-310 - Date and Time API
Expert Group Member das JSRs 207 (PD4J), 250 (Common Annotations), 270 (Java 2 SE 6.0), 296 (Swing Framework) e 303 (Bean Validation)
SouJava: Fortalecendo a comunidade Java brasileira - https://soujava.dev.java.net/ https://www.soujava.org.br/
JSR Community @ java.net - http://community.java.net/jsr
Blogs - http://blog.michaelnascimento.com.br/ http://today.java.net/pub/au/80
Twitter - @mr__m
[WWW]
skill_ufmt
JavaEvangelist
[Avatar]

Membro desde: 20/05/2003 18:02:23
Mensagens: 318
Localização: Cuiabá - MT
Offline

Como é que vocês fazem, quando ocorre algo deste tipo, uma chave composta que um dos campos é sequencial?

Criam um novo campo que distinguirá cada registro tornado este chave primária, passando a composta para chave única e continuam fazendo as buscas normais por esta chave única?

Como é feito num banco onde exitem grandes massas de dados?

Deve ter um modo, isso é rotineiro de se acontecer, ou não?

Windows: Not Plug & Play, but Bug & Pay!
_________________________________________________
Kivanio Pereira Barbosa
Bacharel em Ciência da Computação

CUIABÁ JAVA USERS
www.cajumt.com.br
[WWW] aim icon [MSN] [ICQ]
mister__m
Virtual Machine Man
[Avatar]

Membro desde: 18/03/2005 16:13:17
Mensagens: 736
Offline

Explique seu caso de uso para isso

Normalmente isso é coisa de usuário que acha "bonito" ser assim. Por que 10 1, 11 2, 10 3 não atende?

Michael Nascimento Santos, aka Mister M

Summa Technologies do Brasil - http://www.summa-tech.com/
genesis: Uma nova forma de desenvolver aplicações - https://genesis.dev.java.net/
ThinNB: Suporte a Thinlet no NetBeans - https://thinnb.dev.java.net/
Líder da JSR-310 - Date and Time API
Expert Group Member das JSRs 207 (PD4J), 250 (Common Annotations), 270 (Java 2 SE 6.0), 296 (Swing Framework) e 303 (Bean Validation)
SouJava: Fortalecendo a comunidade Java brasileira - https://soujava.dev.java.net/ https://www.soujava.org.br/
JSR Community @ java.net - http://community.java.net/jsr
Blogs - http://blog.michaelnascimento.com.br/ http://today.java.net/pub/au/80
Twitter - @mr__m
[WWW]
louds
Moderador
[Avatar]

Membro desde: 29/04/2003 23:09:15
Mensagens: 4061
Localização: São Paulo
Offline

Hmm, você não poderia travar os registros primeiro.

select * from x where x.pk0 = ? for update


Isso vai te garantir o sequênciamento correto e paralelismo entre seqüências diferentes.
O problema é quando inserir o primeiro, para isso você pode travar um tabela secundária.

Fora isso, recomento pegarem algum expert oracle/j2ee para ajudar nessa situação.


http://www.kumpera.net/blog/
http://www.mono-project.com/
"Each individual should work for himself. People will not sacrifice themselves for the company. They come to work at the company to enjoy themselves."
Soichiro Honda
[ICQ]
foia
JavaGuru
[Avatar]

Membro desde: 26/09/2003 16:29:51
Mensagens: 212
Localização: tiquipaya city
Offline

v se isso ajuda...

-------------

-------------


fôia

This message was edited 2 times. Last update was at 19/04/2005 18:44:09


fôia
-----------------------
Ahhhhh meu saquinho !!!
[WWW]
louds
Moderador
[Avatar]

Membro desde: 29/04/2003 23:09:15
Mensagens: 4061
Localização: São Paulo
Offline

Inacreditavel nesse projeto são 2 coisas.

A porta que usou select max/count para gerar chave primaria, isso é uma das primeiras coisas que você aprende que não escala para mais de UM usuario simultâneo.

Um projeto que vai ter toda essa carga só receber testes de stress um dia antes.

Sinceramente? Sejam honestos com o cliente ou criem diversão suficiênte para corrigir o problema por baixo dos panos.

This message was edited 1 time. Last update was at 19/04/2005 18:39:45


http://www.kumpera.net/blog/
http://www.mono-project.com/
"Each individual should work for himself. People will not sacrifice themselves for the company. They come to work at the company to enjoy themselves."
Soichiro Honda
[ICQ]
skill_ufmt
JavaEvangelist
[Avatar]

Membro desde: 20/05/2003 18:02:23
Mensagens: 318
Localização: Cuiabá - MT
Offline

mister__m wrote:Eu nunca disse que ia ficar "bonitinho" assim

Mas, por que não pode ser 10 1, 11 2, 10 3? Pelo que eu entendi, o importante é não coincidir e manter a ordem, não?


pode ser assim sim mister.

Acontece o seguinte, para que eu possa inserir nas outras tabelas e nessa eu só preciso ter o próximo número que estará no segundo campo, sem usar MAX.

+- isso: select numero maior do campo2 onde campo = algum valor

Windows: Not Plug & Play, but Bug & Pay!
_________________________________________________
Kivanio Pereira Barbosa
Bacharel em Ciência da Computação

CUIABÁ JAVA USERS
www.cajumt.com.br
[WWW] aim icon [MSN] [ICQ]
mister__m
Virtual Machine Man
[Avatar]

Membro desde: 18/03/2005 16:13:17
Mensagens: 736
Offline

Se for assim, usa uma sequence!

Michael Nascimento Santos, aka Mister M

Summa Technologies do Brasil - http://www.summa-tech.com/
genesis: Uma nova forma de desenvolver aplicações - https://genesis.dev.java.net/
ThinNB: Suporte a Thinlet no NetBeans - https://thinnb.dev.java.net/
Líder da JSR-310 - Date and Time API
Expert Group Member das JSRs 207 (PD4J), 250 (Common Annotations), 270 (Java 2 SE 6.0), 296 (Swing Framework) e 303 (Bean Validation)
SouJava: Fortalecendo a comunidade Java brasileira - https://soujava.dev.java.net/ https://www.soujava.org.br/
JSR Community @ java.net - http://community.java.net/jsr
Blogs - http://blog.michaelnascimento.com.br/ http://today.java.net/pub/au/80
Twitter - @mr__m
[WWW]
 
Índice dos Fóruns » Arquitetura de Sistemas
Ir para:   
Powered by JForum 2.1.8 © JForum Team