Pessoal, preciso de ajuda para entender o motivo de uma trigger
bloquear um select (update em outra tabela com sub select).
Vejam o exemplo:
Minhas duas tabelas:
create table tb_produtoestoque (
id integer not null,
produto_id integer not null,
qt_estoque numeric(18,4) not null);
alter table tb_produtoestoque add constraint produtoestoque_pk primary key(id);
--alter table tb_produtoestoque add constraint prodestoque_prod_fk
foreign key (produto_id) references tb_produto(id);
create table tb_produtoestoquehistorico (
id integer not null,
produtoestoque_id integer not null,
qt_estoquehistorico numeric(18,4) not null,
dt_cadastro timestamp default current_timestamp not null,
dt_processamento timestamp);
alter table tb_produtoestoquehistorico add constraint
produtoestoquehistorico_pk primary key(id);
alter table tb_produtoestoquehistorico add constraint
prodhistorico_prodestoque_fk foreign key (produtoestoque_id)
references tb_produtoestoque(id);
create sequence seq_produtoestoquehistorico;
Trigger na tabela produtoestoquehistorico:
create or replace function pct_produtoestoquehistorico() returns trigger as $$
declare
begin
if ((new.id is null) or (new.id < 1)) then
new.id := nextval('seq_produtoestoquehistorico');
end if;
return NEW;
end;
$$ language 'plpgsql';
create trigger trg_produtoestoquehistorico before insert on
tb_produtoestoquehistorico for each row execute procedure
pct_produtoestoquehistorico();
Zerando os estoques dos produtos 1, 2 e 3 :
insert into tb_produtoestoque values (1, 1, 0), (2, 2, 0), (3, 3, 0);
Inserindo historico para os produtos 1, 2 e 3 cada um com 2
quantidades totalizando um estoque de 3uni por produto:
insert into tb_produtoestoquehistorico
values (null, 1, 1, CURRENT_TIMESTAMP, null), (null, 1, 2,
CURRENT_TIMESTAMP, null),
(null, 2, 1, CURRENT_TIMESTAMP, null), (null, 2, 2,
CURRENT_TIMESTAMP, null),
(null, 3, 1, CURRENT_TIMESTAMP, null), (null, 3, 2,
CURRENT_TIMESTAMP, null);
Agora, em uma transação isolada: inserir um novo registro de histórico
para o produto 1
begin;
insert into tb_produtoestoquehistorico values (null, 1, 1,
CURRENT_TIMESTAMP, null);
Mantendo a transação anterior aberta (utilizando outro terminal), em
uma nova transação atualizar o estoque do produto 1:
begin;
update tb_produtoestoque set
qt_estoque = qt_estoque + coalesce((select sum(t1.qt_estoquehistorico)
from
tb_produtoestoquehistorico t1
where
t1.produtoestoque_id = tb_produtoestoque.id
and
t1.dt_processamento is null), 0)
where id in (select t1.produtoestoque_id
from tb_produtoestoquehistorico t1
where t1.dt_processamento is null);
Percebam que o update ficou aguardando a primeira transação.
Porque o update na tabela produtoestoque é mantido em waiting?
Porque a trigger manteve o lock (ExclusiveLock) sobre a tabela de histórico?
Utilizo PostgreSQL 9.2.4
_______________________________________________
pgbr-geral mailing list
[email protected]
https://listas.postgresql.org.br/cgi-bin/mailman/listinfo/pgbr-geral