Unix Technical Forum

Database Insertion commitment

This is a discussion on Database Insertion commitment within the Pgsql General forums, part of the PostgreSQL category; --> Hi, If I have a series of Insert statements within a loop in a function on the same table. ...


Go Back   Unix Technical Forum > Database Server Software > PostgreSQL > Pgsql General

FAQ Members List Calendar Search Today's Posts Mark Forums Read
  #1 (permalink)  
Old 04-09-2008, 07:18 PM
Jasbinder Singh Bali
 
Posts: n/a
Default Database Insertion commitment

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

Digg this Post!Add Post to del.icio.usBookmark Post in TechnoratiFurl this Post!
Reply With Quote
  #2 (permalink)  
Old 04-09-2008, 07:18 PM
A. Kretschmer
 
Posts: n/a
Default Re: Database Insertion commitment

am Mon, dem 09.07.2007, um 2:53:48 -0400 mailte Jasbinder Singh Bali folgendes:
> 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 ?


Inside this function, yes. Outside the function no.


Andreas
--
Andreas Kretschmer
Kontakt: Heynitz: 035242/47150, D1: 0160/7141639 (mehr: -> Header)
GnuPG-ID: 0x3FFF606C, privat 0x7F4584DA http://wwwkeys.de.pgp.net

---------------------------(end of broadcast)---------------------------
TIP 5: don't forget to increase your free space map settings

Digg this Post!Add Post to del.icio.usBookmark Post in TechnoratiFurl this Post!
Reply With Quote
  #3 (permalink)  
Old 04-09-2008, 07:18 PM
Viatcheslav Kalinin
 
Posts: n/a
Default Re: Database Insertion commitment

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.


---------------------------(end of broadcast)---------------------------
TIP 1: if posting/reading through Usenet, please send an appropriate
subscribe-nomail command to majordomo@postgresql.org so that your
message can get through to the mailing list cleanly

Digg this Post!Add Post to del.icio.usBookmark Post in TechnoratiFurl this Post!
Reply With Quote
  #4 (permalink)  
Old 04-09-2008, 07:18 PM
Jasbinder Singh Bali
 
Posts: n/a
Default Re: Database Insertion commitment

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> 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.
>
>


Digg this Post!Add Post to del.icio.usBookmark Post in TechnoratiFurl this Post!
Reply With Quote
  #5 (permalink)  
Old 04-09-2008, 07:18 PM
Ragnar
 
Posts: n/a
Default Re: Database Insertion commitment

On mán, 2007-07-09 at 11:24 +0400, Viatcheslav Kalinin wrote:
> Jasbinder Singh Bali wrote:
> > 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 ?

> Functions are run in a single separate transaction


this is not correct.

functions run in the transaction where they were called,
not in a separate one.

gnari



---------------------------(end of broadcast)---------------------------
TIP 9: In versions below 8.0, the planner will ignore your desire to
choose an index scan if your joining column's datatypes do not
match

Digg this Post!Add Post to del.icio.usBookmark Post in TechnoratiFurl this Post!
Reply With Quote
  #6 (permalink)  
Old 04-09-2008, 07:18 PM
Viatcheslav Kalinin
 
Posts: n/a
Default Re: Database Insertion commitment

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?


---------------------------(end of broadcast)---------------------------
TIP 5: don't forget to increase your free space map settings

Digg this Post!Add Post to del.icio.usBookmark Post in TechnoratiFurl this Post!
Reply With Quote
  #7 (permalink)  
Old 04-09-2008, 07:18 PM
Ragnar
 
Posts: n/a
Default Re: Database Insertion commitment

On mán, 2007-07-09 at 03:34 -0400, 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.


maybe you should provide us with a simple test case, to illustrate your
problem.

gnari



---------------------------(end of broadcast)---------------------------
TIP 9: In versions below 8.0, the planner will ignore your desire to
choose an index scan if your joining column's datatypes do not
match

Digg this Post!Add Post to del.icio.usBookmark Post in TechnoratiFurl this Post!
Reply With Quote
  #8 (permalink)  
Old 04-09-2008, 07:18 PM
Jasbinder Singh Bali
 
Posts: n/a
Default Re: Database Insertion commitment

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

Digg this Post!Add Post to del.icio.usBookmark Post in TechnoratiFurl this Post!
Reply With Quote
  #9 (permalink)  
Old 04-09-2008, 07:18 PM
Viatcheslav Kalinin
 
Posts: n/a
Default Re: Database Insertion commitment

Jasbinder Singh Bali wrote:
>
> 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.

This is most likely it if I understand you scheme right.

---------------------------(end of broadcast)---------------------------
TIP 4: Have you searched our list archives?

http://archives.postgresql.org/

Digg this Post!Add Post to del.icio.usBookmark Post in TechnoratiFurl this Post!
Reply With Quote
  #10 (permalink)  
Old 04-09-2008, 07:18 PM
Jasbinder Singh Bali
 
Posts: n/a
Default Re: Database Insertion commitment

On 7/9/07, Viatcheslav Kalinin <vka@ipcb.net> wrote:
>
> Jasbinder Singh Bali wrote:
> >
> > 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.

> This is most likely it if I understand you scheme right.
>


Do you see any work around for this?
Nothing that I could think of.

Digg this Post!Add Post to del.icio.usBookmark Post in TechnoratiFurl this Post!
Reply With Quote
Reply


Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

vB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are On
Forum Jump


All times are GMT. The time now is 08:03 AM.


Powered by vBulletin® Version 3.6.5
Copyright ©2000 - 2008, Jelsoft Enterprises Ltd.
Search Engine Optimization by vBSEO 3.2.0
www.UnixAdminTalk.com