Em 3 de março de 2011 10:29, Fernando Wobeto
<[email protected]> escreveu:
> Tiago, muito interessante este SELECT FOR UPDATE, ainda não o conheço. Você
> poderia me dar um exemplo pratico da utilização dele para o mesmo propósito
> que vc informou abaixo?
>

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


-- 
TIAGO J. ADAMI
http://www.adamiworks.com
_______________________________________________
pgbr-geral mailing list
[email protected]
https://listas.postgresql.org.br/cgi-bin/mailman/listinfo/pgbr-geral

Responder a