Eu apenas fico preocupado com um tipo de campo integer que precisa ser sequencial, sem furos na sequencia e nao podendo serem duplicados e um sistema deste implantado em um cliente com mais de 200 estações que ficam povoando as tabelas todo o tempo...
Em 4 de março de 2011 00:46, Fernando Brombatti <[email protected]>escreveu: > Dependendo da tua situação podes, usar uma união de SEQUENCES e INSERT > RETURNING. > > 2011/3/3 Flavio Henrique Araque Gurgel <[email protected]> > > > Bem, não fiz algo muito bem feito, mas pode ilustrar bem o >> > funcionamento do SELECT FOR UPDATE: >> > >> > CREATE TABLE CONTADOR( >> > ID INTEGER NOT NULL, >> > DESCRICAO VARCHAR(30) NOT NULL, >> > VALOR INTEGER NOT NULL >> > ); >> > >> > ALTER TABLE CONTADOR ADD PRIMARY KEY( id ); >> > >> > -- Função que retorna o último contador gravado e incrementa 1 ao final >> > CREATE OR REPLACE FUNCTION UF_ADD_CONTADOR( ai_id INTEGER ) >> > RETURNS INTEGER AS >> > $BODY$ >> > DECLARE >> > li_id INTEGER; >> > BEGIN >> > -- Pega o valor. A cláusula FOR UPDATE faz um ROW LOCK EXCLUSIVE >> > -- apenas sobre o registro especificado. Somente após um COMMIT >> ou >> > -- ROLLBACK o LOCK será liberado. >> > -- NOTA: o registro deve existir na tabela. Você pode fazer o >> tratamento >> > -- para criá-lo caso não exista ou então deixar pré-cadastrado >> > SELECT >> > valor >> > INTO >> > li_id >> > FROM >> > contador >> > WHERE >> > id = ai_id >> > FOR UPDATE; >> > >> > -- Incrementa o valor do contador >> > UPDATE >> > contador >> > SET >> > valor = valor +1 >> > WHERE >> > id = ai_id; >> > >> > -- Retorna o valor >> > RETURN li_id; >> > END >> > $BODY$ >> > LANGUAGE 'plpgsql' VOLATILE; >> > >> > >> > -- Insere o registro na tabela de contador para que possa ser >> incrementado >> > INSERT INTO contador ( id, descricao, valor ) VALUES( 1, 'Contador >> Teste', 1 ); >> > >> > -- Para recuperar o valor dentro de uma transação... >> > -- NOTA: se outra transação estiver executando o mesmo comando, ela irá >> aguardar >> > -- até que a primeira transação realize um ROLLBACK ou COMMIT. >> > -- Caso um ROLLBACK seja executado, o valor não é incrementado. >> > SELECT uf_add_contador( 1 ) as valor >> >> Sinto muito, mas essa implementação pode ter um efeito colateral. Duas >> transações concorrentes podem "catar" o mesmo valor. O SELECT... FOR >> UPDATE não impede a leitura do registro. >> Pode ocorrer um ROLLBACK automático na transação que chegar por último >> na hora fizer o UPDATE da sua função. Se a aplicação não tratar esse >> ROLLBACK (e tentar novamente até conseguir sucesso no COMMIT) isso >> pode se tornar uma bola de neve e um catastrófico "lock geral" numa >> aplicação com muita concorrência. >> >> A implementação de sequências foi inventada exatamente pra isso, sem >> dor de cabeça. Não acho legal tentar contornar por fora algo que um >> banco de dados sério sabe fazer com maestria. >> >> []s >> Flavio Gurgel >> _______________________________________________ >> pgbr-geral mailing list >> [email protected] >> https://listas.postgresql.org.br/cgi-bin/mailman/listinfo/pgbr-geral >> > > > > -- > Fernando Brombatti > email-msn-gtalk-skype: > [email protected] > work: +55 54 3218-6060 > home: +55 54 3028-7217 > mobile: +55 54 9189-7970 > > _______________________________________________ > pgbr-geral mailing list > [email protected] > https://listas.postgresql.org.br/cgi-bin/mailman/listinfo/pgbr-geral > > -- Fernando Wobeto Desenvolvedor Web [email protected]
_______________________________________________ pgbr-geral mailing list [email protected] https://listas.postgresql.org.br/cgi-bin/mailman/listinfo/pgbr-geral
