Preciso obter vários valores de uma sequência com apenas uma consulta. No Stack Overflow, encontrei isto:
https://stackoverflow.com/questions/896274/select-multiple-ids-from-a-postgresql-sequence
A solução parece ser a seguinte:
select nextval('my_sequence') from generate_series(1, N)
Como isso se comporta quando meu aplicativo pode iniciar essa consulta simultaneamente sempre que atende a alguma solicitação do cliente?
A resposta mais votada tem um comentário que diz:
Observe que não há garantia de que os 3 números (nextvals) sejam sequenciais.
Não me importo necessariamente com a sequencialidade, mas é garantido que os valores retornados sejam pelo menos estritamente crescentes monotonicamente, mesmo que possam ser entrelaçados com os valores gerados por outra consulta simultânea?
Sim , a série gerada tem garantia de ser estritamente monotonicamente crescente - para esta consulta simples e
SEQUENCE
com configurações padrão .A
SEQUENCE
pode até ser criada com incremento negativo! E se você adicionar junções, agrupamentosORDER BY
ou qualquer outra coisa à mesma consulta que possa reordenar linhas, isso pode embaralhar os números gerados de acordo, dependendo do plano de consulta resultante.Mas não , sempre pode haver lacunas se transações simultâneas também extraírem da mesma sequência. Use outras ferramentas para números estritamente sequenciais. O manual:
Se cada acesso simultâneo for executado em sua própria sessão, que é fechada depois, você pode usar a
CACHE
configuração de sequências. Mas isso visa principalmente acesso mais rápido e pode resultar em maiores lacunas de sequência para outros padrões de acesso. E nem tenho certeza de que "gapless" é garantido para o cache.Mais sobre o tópico:
Obtenha números estritamente sequenciais com um hack
LOCK
não funciona para sequências.Mas podemos bloquear o objeto de sequência indiretamente com
ALTER SEQUENCE
. O manual:Assumindo os privilégios necessários (!) poderíamos fazer isso, dentro da mesma transação:
Na verdade, não estamos alterando a sequência, mas ela ainda bloqueia todas as interações simultâneas com ela. Portanto, você obtém números estritamente sequenciais. Outras transações envolvidas têm que esperar até que a sua seja concluída e libere o bloqueio. Meio que desafia o propósito de uma sequência de otimizar o acesso de gravação simultânea, temporariamente. Mas você obtém sua série sequencial.
Normalmente, você não desejaria conceder o privilégio a
ALTER SEQUENCE
funções aleatórias. Mas você poderia encapsular esse comando em uma função privilegiada e conceder acesso a essa função a qualquer um - efetivamente concedendo o privilégio de acessar a sequência exclusivamente... Relacionado:Outra anomalia : se sua transação termina em um
ROLLBACK
, a sequência é redefinida para seu estado original, incluindo o número atual antes de suasnextval()
chamadas. Isso nunca acontece em operação normal, mesmo para transações revertidas. Se você continuar a usar esses números, você encontrará violações únicas...