Re: Database Insertion commitment

Поиск
Список
Период
Сортировка
От Jasbinder Singh Bali
Тема Re: Database Insertion commitment
Дата
Msg-id a47902760707090222u668a0b7do78f4d26e44b010cf@mail.gmail.com
обсуждение исходный текст
Ответ на Re: Database Insertion commitment  (Viatcheslav Kalinin <vka@ipcb.net>)
Ответы Re: Database Insertion commitment  (Viatcheslav Kalinin <vka@ipcb.net>)
Re: Database Insertion commitment  (Ragnar <gnari@hive.is>)
Список pgsql-general


On 7/9/07, Viatcheslav Kalinin <vka@ipcb.net> wrote:
Jasbinder Singh Bali wrote:
> My scenario is something like this. I'll try to make it modular and
> simple.
>
> Start Function A (Written in plperlu with no subtransactions)
>      Insert 1 on tbl_abc; (fires trigger A)
>      Insert 2 on tbl_abc; (fires trigger A)
> End Function A
>
> Start Trigger A
>        check the value of col_abc in tbl_abc
>        Start Activity A if col_abc in tbl_abc doesn't is not duplicated.
> End Trigger A
>
> Now, if Insert 1 inserts col_abc  = 'xyz' in tbl_abc
> and Insert 2 inserts the same value of col_abc ='xyz' the its not able
> to see the value of insert 1
> and erroneously starts Activity A that it should not actually.
>
> Do you think I am missing something vital here?
> I'm kind of stuck and confused because fundamentally Insert 2 should
> be able to see the value of Insert 1 as there is no subtransaction
> involved.
>
> Thanks,
> ~Jas
>
> On 7/9/07, *Viatcheslav Kalinin* <vka@ipcb.net <mailto:vka@ipcb.net>>
> wrote:
>
>     Jasbinder Singh Bali wrote:
>     > Hi,
>     >
>     > If I have a series of Insert statements within a loop in a
>     function on
>     > the same table.
>     > Would an Insert be able to see the values of previous insert in
>     that
>     > table ?
>     > I just wanted to know, when would the records be committed, as
>     in, is
>     > it after the whole function is done for with its execution or
>     > right after one single insert.
>     >
>     > Right now what I'm observing is that all the inserts are committed
>     > after the whole function is executed and one insert doesn't see the
>     > value of its previous insert.
>     > In this scenario, how can an insert see the value of its previous
>     > insert even though the whole transaction that lies within the
>     function
>     > is not complete.
>     >
>     > Thanks,
>     > ~Jas
>     Functions are run in a single separate transaction (unless then have
>     BEGIN ... EXCEPTION ... END block inside them which implies
>     subtransaction) thus inside a function all statements can see
>     results of
>     the previous ones just like if you ran them one by one. All
>     changes the
>     function does are committed at the end of the transaction, whether
>     they
>     are visible or not from the outside of that transaction depends on
>     the
>     transaction isolation level. There are only two distinct levels of
>     isolation in Postgresql: READ COMMITTED and SERIALIZABLE, hence
>     uncommitted data can never be seen before the transaction which
>     changed
>     them is over, the second one makes transaction fully independent
>     just as
>     the name states.
>
>

Hmm, afaik triggers are run within the same transaction so it shouldn't
really matter if the trigger is involved. I've made some tests too
(written in plpgsql, I hope you are fine with it):

CREATE TABLE test (x varchar);

CREATE OR REPLACE FUNCTION "public"."test_trg" () RETURNS trigger AS
$body$
BEGIN
    perform 1 from test1 where x = new.x;
    if not found then
         raise info 'not found';
    else
         raise info 'found';
    end if;

    return new;
END;
$body$
LANGUAGE 'plpgsql' VOLATILE CALLED ON NULL INPUT SECURITY INVOKER;

CREATE TRIGGER "trigger1" BEFORE INSERT
ON "public"."test" FOR EACH ROW
EXECUTE PROCEDURE "public"."test_trg"();

CREATE OR REPLACE FUNCTION "public"."test" () RETURNS "pg_catalog"."void" AS
$body$
begin
    insert into test values ('xxx');
    insert into test values ('xxx');
end;
$body$
LANGUAGE 'plpgsql' VOLATILE CALLED ON NULL INPUT SECURITY DEFINER;
----------------

select test();

>INFO:  not found
>CONTEXT:  SQL statement "INSERT INTO test values ('xxx')"
>PL/pgSQL function "test" line 5 at SQL statement
>INFO:  found
>CONTEXT:  SQL statement "INSERT INTO test values ('xxx')"
>PL/pgSQL function "test" line 6 at SQL statement


As you can see it has found inserted value on the second insert. Could
it be that you misused after trigger instead of before?


The only difference between you test case my a sample test case that I would provide is the Perform part in the trigger function.

In my program Perform part is about opening a socket connection with a Unix Tools server that runs traceroute and populates records in  table test.

Before this Perform part, I would check if table test has one row whose col1 value is 'xyz' say.

If No, then Perform
else
 don't perform.

One reason I see that new insert does't see the values of old insert is because as soon as socket connection is established, my trigger returns and 1st insert is complete even though I'm not sure whether the unix tools server has already inserted values in table test or not. There might be a time lag based on how fast traceroute returns, though right now its very fast.


Any comments?

Thanks,
Jas

В списке pgsql-general по дате отправления:

Предыдущее
От: Ragnar
Дата:
Сообщение: Re: How to obtain a sequence's increment value from the system catalog
Следующее
От: Viatcheslav Kalinin
Дата:
Сообщение: Re: Database Insertion commitment