inacreditÁvel

Sequence não é como campo identity. Você é que é responsável por ler o valor da sequence, por sinal. Não tem razão pra não funcionar.

Agora, que muitos frameworks de mapeamento O/R não sabem lidar sozinhos com a segunda sequence já é outro problema…

Pelo que eu entendi até agora, o uso de sequence é bem superior.

Sequence não é como campo identity. Você é que é responsável por ler o valor da sequence, por sinal. Não tem razão pra não funcionar.

Agora, que muitos frameworks de mapeamento O/R não sabem lidar sozinhos com a segunda sequence já é outro problema…[/quote]

segundo alguns experiente aqui, isso não funciona, não é possível fazer uma sequence para o segundo campo.

como é possível retornar uma sequence para o segundo campo, mister, seguindo que busco a sequence da maneira abaixo?

SELECT NOMEDASEQUENCE.NEXTVAL FROM DUAL

Não vejo como, sempre me retorna um campo :frowning:

No comments :mrgreen:

[quote=skill_ufmt]como é possível retornar uma sequence para o segundo campo, mister, seguindo que busco a sequence da maneira abaixo?

SELECT NOMEDASEQUENCE.NEXTVAL FROM DUAL

Não vejo como, sempre me retorna um campo :frowning:
[/quote]

Dois selects ou um:

Que tal usar um esquema parecido a um dos métodos de locking do sybase, hashed locking.

Crie 1 tabela auxiliar com uns X registros, onde X é 2-3 vezes o tipo de usuarios simultâneos do teu sistema.

No teu código java faça hashing para espalhar a primeira parte da PK no intervalo de valores da tabela que acabou de criar.

De um select for update em um registro apenas da tabela auxiliar, vai ser via PK e ter poucos registros, então vai ser rápido.

Pronto, melhor que isso começa estourar o budget de minutos que você tem para arrumar isso.

No comments :mrgreen:

[quote=skill_ufmt]como é possível retornar uma sequence para o segundo campo, mister, seguindo que busco a sequence da maneira abaixo?

SELECT NOMEDASEQUENCE.NEXTVAL FROM DUAL

Não vejo como, sempre me retorna um campo :frowning:
[/quote]

Dois selects ou um:

Calam mister não se exalte hehe, mas como vou referenciar um campo especifico para esta sequence, aqui no oracle não me deixa fazer referência a campo na criação da sequence. É uma sequence só, posso ter noms diferentes de sequences mas me retorna a emsa coisa :frowning:

[quote=louds]Que tal usar um esquema parecido a um dos métodos de locking do sybase, hashed locking.

Crie 1 tabela auxiliar com uns X registros, onde X é 2-3 vezes o tipo de usuarios simultâneos do teu sistema.

No teu código java faça hashing para espalhar a primeira parte da PK no intervalo de valores da tabela que acabou de criar.

De um select for update em um registro apenas da tabela auxiliar, vai ser via PK e ter poucos registros, então vai ser rápido.

Pronto, melhor que isso começa estourar o budget de minutos que você tem para arrumar isso.
[/quote]

Hehe, cara seis são demais :slight_smile:

Mas já estou acreditando que isso não será entregue amanha kkkk

[quote=skill_ufmt]Calam mister não se exalte hehe, mas como vou referenciar um campo especifico para esta sequence, aqui no oracle não me deixa fazer referência a campo na criação da sequence. É uma sequence só, posso ter noms diferentes de sequences mas me retorna a emsa coisa :frowning:
[/quote]

Cara, acho que você está meio perdido. Uma sequence não está relacionada a campo nenhum no Oracle. Seu código é que relaciona.

Então você tem que conseguir usar criar n sequences ou até usar a mesma pros dois campos.

 A sua aplicação é DONA do banco ou outras aplicações fazem atualizações nesta mesma tabela ( INSERTs ) ?
  
 Se a aplicação tem acesso exclusivo de escrita nesta tabela basta vc isolar o acesso a esta tabela e sincronizar o acesso ä mesma, mais ou menos assim:
public class KeyGenerator{
      private Map keys = new HashMap();

      public sinchronized Integer getNext( Integer mainKey ){
            // SELECT MAX(secondKey) FROM TABLE WHERE MAIN_KEY = ?
            Integer current = // resultado da query ou zero caso seja a                   primeira
            Integer old = (Integer) keys.get(mainKey);
            if( old == null ){
                old = new Integer(0);
            }
             Integer result = Math.max( old.intValue() , current.intValue()) + 1;
             keys.put( mainKey , result );
             return result;
      }
}
    
 Assim vc tem controle sobre as outras threads e de vez em quando vc pode esvaziar esta cache de acordo com um tempo pré-determinado.

[quote=CLAUDIO GUALBERTO]
Assim vc tem controle sobre as outras threads e de vez em quando vc pode esvaziar esta cache de acordo com um tempo pré-determinado.[/quote]

Parece interessante, mas está me parecendo o que já tenho no momento dando problema, não saquei a questão do cache que tu falou.

[quote=mister__m][
Cara, acho que você está meio perdido. Uma sequence não está relacionada a campo nenhum no Oracle. Seu código é que relaciona.

Então você tem que conseguir usar criar n sequences ou até usar a mesma pros dois campos.[/quote]

Completamente perdido hehe
Vo ver isso amanha, essa questão de várias sequences e volto a postar aqui, ok?

Olá,

Nao tinha visto este post antes. Vamos la ver se ajuda em algo.

Skill teu problema é a conhecida sequence in parent pelos DBA’s, existem algumas solucoes. O pessoal ja mostrou algumas, mas eu particularmente quando precisei usar isso fiz da seguinte maneira. Essa solucao é adequada se tu nao precisa ter uma sequencia uniforme dos codigos, ou seja, nao tenha problema em falhar algum codigo.

10 1 10 2 10 4 11 3 11 7

Nesse caso tu pode criar o registro vazio no incio da transacao, locar ele com select for update e depois ir fazendo o update no mesmo.
Claro isso cheira meio a uma gambiarra, mas para o problema resolve e nao da dor de cabeca.

Utilizar sequence é uma boa pedida, eu so nao entendi porque tu fez tanta confusao sobre o uso dela.

Outra coisa que notei nos topicos anteriores foi tu falando que o Oracle loca a tabela. Isso nao é verdade o Oracle loca somente os registros alterados. Pode ter certeza que se a aplicacao ta parando quando tem um unico registro locado de duas uma, ou estao tentando alterar o registro locado (nao a tabela, esta nao é locada a menos que tu force isso) ou o servidor nao ta aguentando as requisicoes e ta colocando processos em fila.

Sinceramente é meio chatinho de arrumar isso dependendo de como tua aplicacao foi feita, mas nada impossivel.

Qualquer coisa poste ai.

]['s

[quote=skill_ufmt][quote=mister__m][
Cara, acho que você está meio perdido. Uma sequence não está relacionada a campo nenhum no Oracle. Seu código é que relaciona.

Então você tem que conseguir usar criar n sequences ou até usar a mesma pros dois campos.[/quote]

Completamente perdido hehe
Vo ver isso amanha, essa questão de várias sequences e volto a postar aqui, ok?[/quote]

Skill,

Imagine uma sequence como uma grande tabela que armazena valores sequenciais.

1 2 3 ... 100000000000000000

Agora imagina o SELECT

O que ele faz, retorna o proximo valor “liberado” na tabela, seria semelhante com isso.
Imaginando que tu tenha uma tabela auxiliar pra armazenar codigos sequenciais.

A diferenca da sequence é que tu nao consegue usar um codigo que ja foi soliciatado com o NEXTVAL. O maximo que tu consegue saber é o codigo atual usando CURRVAL.

Para inserir em uma tabela com usando sequence seria ± assim.

CREATE TABLE teste (codigo NUMBER ,descricao VARCHAR2(200))

Deve ter erro de sintaxe, mas a idéia de como fazer é essa.

]['s

[quote=fabgp2001]
Qualquer coisa poste ai.

]['s[/quote]

Fábio, respondendo a seus dois post, ok?

Bom, as coisas não estavm sendo feitas por SEQUENCES, quem gerenciava era a maldita classe com um select max comum.

Quando descobri tal fato, me dirigi ao gerente e o mesmo não acreditou que as coisas estavam nesse nível, mas enfim, discutimos e tiveram que por as tais sequences no oracle, isso afetou a minha aplicação e mais umas 3 que estavam entrando em produção nas quais detectei o mesmo problema.

É dificil acreditar, mas foi isso que aconteceu.

Foram feitos todos os sequences nas tabelas e todas estão funcionando perfeitamente, com exceção desta minha tabela principal que tem as chaves compostas.

O meu forte não é BD, só sei oque não se pode fazer hehe e creio que deveriam ter um DBA para isso, mas enfim.

Pelo que foi me passado, na vrdade rolou uma reunião com o pessoal que tem experiência dentro da empresa, e rolaram idéias, a maioria já citadas aqui.

A soluçaõ que tava discutindo com o mister_m, e acho que essa mesma que vc postou, foi desconsireda, porque segundo eles, a sequence não poderia ser usada em chave composta.

O mister_m me disse que pode, então vo ver isso amanha.

Quanto ao lock de tabela, realmente estava me referindo a lock naquele registro em questão que estaria seno usado, neste estaria tudo locado inclusive seus relacionamentos, certo? os outros 2999 não poderiam operar nada nele, certo?

Dai surgiu a idéia de usar a tabela auxiliar, e fazer lock nela em vez de na minha tabela principal, inicial era uma trigger qeu faria, mas o cliente vetou isso, então eu teria que controlar isso via aplicação, dai caimos no mesmo fato, por que a aplicação gerenciaria isso? e se me ocorre uma falha igual a que ocorreu, quem me garante a unicidade da chave? isso usando um select max, se fosse um equence daria certo, mas ai novamete teria a idéia de que a sequence não funcionaria porque a tabela auxiliar tbm seria de dois campos, dai esta idéia minguo novamente.

Quanto a usar o for update para dar lock no registro, era a solução melhor, só que novamente caiu em discussão que se eu tivesse 3000, 2999 em lock, e por acaso desse problema na app, seria feito um rollback, mas isso liberaria os 2999 caras, e ai boom n app novamente ehhe.
Essa informação foi desmentida por um amigo meu depois, segundo ele seria liberado somente o próximo cara da fila mesmo usando um for update.

Acho que ai surgiria o problema dessa fila de caras esperando a liberação do registro, isso me daria um belo problema tbm, ou não? sem dizer que o sistema é web, e os usuários ficariam loucos hehe talvez até um timeout ocorresse, ou vários refresh(F5), o que acho tbm ocorreria mais fila :slight_smile:

Dai surgiu a idéia de seprarmos em uma classe o for update, , onde eu daria lock, incrementaria o valor, inseria na tabela, e libera a mesma, a cda acesso eu teria um valor novo, e seria uma operação teoricamente mais rápida de ser feita.

Acho que agora explanei mais como ta a coisa, talvez eu esteja aumenta a complexidade da coisa, mas é por ae.

Só pra deixar bem claro: sequences são como contadores independentes dentro do banco, que são incrementados quando alguém pede o próximo valor, funcionando fora do contexto transacional, ou, dependendo da forma que você enxerga, num contexto transacional completamente isolado do atual e sem nunca dar rollback.

Já que sequences são contadores, não tem nada a ver com as tabelas e podem ser usados da forma que quisermos. Normalmente, usamos para incrementar sequencialmente o valor de uma coluna em uma tabela, mas nada impede outros usos ou o uso para mais de uma coluna de uma tabela.

Em suma, a menos que te proíbam de usar sequences para resolver o seu problema ou exista alguma limitação de negócio, seja feliz :slight_smile:

[quote=mister__m]
Em suma, a menos que te proíbam de usar sequences para resolver o seu problema ou exista alguma limitação de negócio, seja feliz :-)[/quote]

Cara, vo ver esse negócio amanha cedo, se tu tiver certo, vo rezar pra que sua vida seja farta, longa e com muita mulherada hehhe

PS: vi que trampa na suma, conhece o Claudio Miranda? conheci ele por aqui nos eventos do CAJU :slight_smile:

[quote=skill_ufmt][quote=mister__m]
Em suma, a menos que te proíbam de usar sequences para resolver o seu problema ou exista alguma limitação de negócio, seja feliz :-)[/quote]

Cara, vo ver esse negócio amanha cedo, se tu tiver certo, vo rezar pra que sua vida seja farta, longa e com muita mulherada hehhe
[/quote]

Se eu não tiver certo com respeito a sequences não estarem ligadas/limitadas a colunas de tabelas, vou precisar é de terapia pra entender como todos os sistemas que fiz que usam Oracle passaram do primeiro INSERT… :mrgreen:

Além de trabalhar na Summa, ele também faz parte da organização do SouJava. :slight_smile:

[quote=mister__m]
Se eu não tiver certo com respeito a sequences não estarem ligadas/limitadas a colunas de tabelas, vou precisar é de terapia pra entender como todos os sistemas que fiz que usam Oracle passaram do primeiro INSERT… :mrgreen:

Além de trabalhar na Summa, ele também faz parte da organização do SouJava. :-)[/quote]

Vo considerar problema resolvido então hehehe

É também, esqueci desse ponto :slight_smile:
Troquei bastante idéia com ele, ele é daqui de Cuiabá, gente boa, massa ele num restaurante por kg aqui, tavam passando, R$ 0,10 centavos por prato, cara ele apronto um alvoroço, tivemos que filmar a cena toda ehehe, ainda ganhamos desconto depois pra num denunciar kkk, só o Claudio mesmo.

Eu nao vejo motivo para sequence em chave composta nao funcionar, eu ja fiz alguns testes com isso e nao tive problema nenhum.
Afinal ela te retorna dois valores sequenciais unicos, a cada requisiçao.

  É simples,
  o seu problema está ligado com o trasaction isolation level, ou seja, as outras transações só lêm do banco o que está 'comitado', quando vc gera uma nova chave atravéz do SELECT MAX vc precisa guardar este valor em algum lugar fora do banco onde as outras transações ( threads diferentes ) tenham acesso. É o mesmo que dizer "no banco está como 100 , mas já tem outras transações trabalhando com 105" , portanto nossa próxima chave é 106. Note que se transações anteriores falharem vc pode ter uma lacuna na sequencia da chave intermediaria, ou seja, 

10,1
10,2
10,4
10,6
E isto só funciona de verdade se somente a aplicação Java tiver acesso de INSERT nesta tabela.