Dependendo da tua situação podes, usar uma união de SEQUENCES e INSERT RETURNING.
2011/3/3 Flavio Henrique Araque Gurgel <fha...@gmail.com> > > 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 > pgbr-geral@listas.postgresql.org.br > https://listas.postgresql.org.br/cgi-bin/mailman/listinfo/pgbr-geral > -- Fernando Brombatti email-msn-gtalk-skype: bromba...@gmail.com work: +55 54 3218-6060 home: +55 54 3028-7217 mobile: +55 54 9189-7970
_______________________________________________ pgbr-geral mailing list pgbr-geral@listas.postgresql.org.br https://listas.postgresql.org.br/cgi-bin/mailman/listinfo/pgbr-geral