Thread: Atomic operations?

Atomic operations?

From
"Paul Tomblin"
Date:
Ok, I've already written about how my app uses autocommit (although I
have a side project to fix that so you don't need to lecture me about
how bad that is).

I'm doing a simple delete/insert on a table, rather than trying to
figure out whether the row exists or not and then doing an update or
an insert.  But what I'm discovering is that every now and then I get
a duplicate primary key exception, so I figure that two processes are
doing the deletes and inserts and stomping on each other.  So my
question is about combining the delete and insert into one
PreparedStatement.  I've never combined two statements like that, but
somebody on this list mentioned it earlier.  If I say
   PreparedStatement ps = conn.prepareStatement(
      "DELETE FROM venue WHERE venueid = ? ; INSERT INTO VENUE
(venueid, .... ) VALUES(?, ?, ?, ?)");
Does that work?  Will that be atomic so that nobody else can insert
one with that venueid in between the delete and the insert?

--
For my assured failures and derelictions I ask pardon beforehand of my
betters and my equals in my Calling here assembled, praying that in
the hour of my temptations, weakness and weariness, the memory of this
my Obligation and of the company before whom it was entered into, may
return to me to aid, comfort and restrain.

Re: Atomic operations?

From
Dave Cramer
Date:
On 18-Mar-08, at 9:40 AM, Paul Tomblin wrote:

> Ok, I've already written about how my app uses autocommit (although I
> have a side project to fix that so you don't need to lecture me about
> how bad that is).
>
> I'm doing a simple delete/insert on a table, rather than trying to
> figure out whether the row exists or not and then doing an update or
> an insert.  But what I'm discovering is that every now and then I get
> a duplicate primary key exception, so I figure that two processes are
> doing the deletes and inserts and stomping on each other.  So my
> question is about combining the delete and insert into one
> PreparedStatement.  I've never combined two statements like that, but
> somebody on this list mentioned it earlier.  If I say
>   PreparedStatement ps = conn.prepareStatement(
>      "DELETE FROM venue WHERE venueid = ? ; INSERT INTO VENUE
> (venueid, .... ) VALUES(?, ?, ?, ?)");
> Does that work?  Will that be atomic so that nobody else can insert
> one with that venueid in between the delete and the insert?
>
I don't think so, there are two statements there separated by a ; The
window will be much smaller and it will appear to be better, but the
opportunity is still there.

Can't you just check the return value from the delete to see if
anything was deleted ?

Dave

Re: Atomic operations?

From
"Paul Tomblin"
Date:
On Tue, Mar 18, 2008 at 10:06 AM, Dave Cramer <pg@fastcrypt.com> wrote:
>  On 18-Mar-08, at 9:40 AM, Paul Tomblin wrote:
>  > I'm doing a simple delete/insert on a table, rather than trying to
>  > figure out whether the row exists or not and then doing an update or
>  > an insert.  But what I'm discovering is that every now and then I get
>  > a duplicate primary key exception, so I figure that two processes are
>  > doing the deletes and inserts and stomping on each other.  So my
>
>  Can't you just check the return value from the delete to see if
>  anything was deleted ?

I'm not sure how that would help.  If I do the delete and it didn't
delete anything, that doesn't tell me if some other process inserted
it in the meantime.




--
For my assured failures and derelictions I ask pardon beforehand of my
betters and my equals in my Calling here assembled, praying that in
the hour of my temptations, weakness and weariness, the memory of this
my Obligation and of the company before whom it was entered into, may
return to me to aid, comfort and restrain.

Re: Atomic operations?

From
Dave Cramer
Date:
On 18-Mar-08, at 10:12 AM, Paul Tomblin wrote:

> On Tue, Mar 18, 2008 at 10:06 AM, Dave Cramer <pg@fastcrypt.com>
> wrote:
>> On 18-Mar-08, at 9:40 AM, Paul Tomblin wrote:
>>> I'm doing a simple delete/insert on a table, rather than trying to
>>> figure out whether the row exists or not and then doing an update or
>>> an insert.  But what I'm discovering is that every now and then I
>>> get
>>> a duplicate primary key exception, so I figure that two processes
>>> are
>>> doing the deletes and inserts and stomping on each other.  So my
>>
>> Can't you just check the return value from the delete to see if
>> anything was deleted ?
>
> I'm not sure how that would help.  If I do the delete and it didn't
> delete anything, that doesn't tell me if some other process inserted
> it in the meantime.
>
which ever process succeeds in deleting should do the insert.

Dave
>
>
>
> --
> For my assured failures and derelictions I ask pardon beforehand of my
> betters and my equals in my Calling here assembled, praying that in
> the hour of my temptations, weakness and weariness, the memory of this
> my Obligation and of the company before whom it was entered into, may
> return to me to aid, comfort and restrain.


Re: Atomic operations?

From
"Paul Tomblin"
Date:
On Tue, Mar 18, 2008 at 10:17 AM, Dave Cramer <pg@fastcrypt.com> wrote:
>  >> On 18-Mar-08, at 9:40 AM, Paul Tomblin wrote:
>  >>> I'm doing a simple delete/insert on a table, rather than trying to
>  >>> figure out whether the row exists or not and then doing an update or
>  >>> an insert.  But what I'm discovering is that every now and then I

>  >> Can't you just check the return value from the delete to see if
>  >> anything was deleted ?
>  >
>  > I'm not sure how that would help.  If I do the delete and it didn't
>  > delete anything, that doesn't tell me if some other process inserted
>  > it in the meantime.
>  >
>  which ever process succeeds in deleting should do the insert.

Doesn't help in the case where the record wasn't in there in the first place.

--
For my assured failures and derelictions I ask pardon beforehand of my
betters and my equals in my Calling here assembled, praying that in
the hour of my temptations, weakness and weariness, the memory of this
my Obligation and of the company before whom it was entered into, may
return to me to aid, comfort and restrain.

Re: Atomic operations?

From
Dave Cramer
Date:
On 18-Mar-08, at 11:05 AM, Paul Tomblin wrote:

> On Tue, Mar 18, 2008 at 10:17 AM, Dave Cramer <pg@fastcrypt.com>
> wrote:
>>>> On 18-Mar-08, at 9:40 AM, Paul Tomblin wrote:
>>>>> I'm doing a simple delete/insert on a table, rather than trying to
>>>>> figure out whether the row exists or not and then doing an
>>>>> update or
>>>>> an insert.  But what I'm discovering is that every now and then I
>
>>>> Can't you just check the return value from the delete to see if
>>>> anything was deleted ?
>>>
>>> I'm not sure how that would help.  If I do the delete and it didn't
>>> delete anything, that doesn't tell me if some other process inserted
>>> it in the meantime.
>>>
>> which ever process succeeds in deleting should do the insert.
>
> Doesn't help in the case where the record wasn't in there in the
> first place.
>

What you are looking for is upsert. It's on the todo list http://www.postgresql.org/docs/faqs.TODO.html

In the meantime you can lock the table or create a function to do a
select and update or insert.

Dave
> --
> For my assured failures and derelictions I ask pardon beforehand of my
> betters and my equals in my Calling here assembled, praying that in
> the hour of my temptations, weakness and weariness, the memory of this
> my Obligation and of the company before whom it was entered into, may
> return to me to aid, comfort and restrain.
>
> --
> Sent via pgsql-jdbc mailing list (pgsql-jdbc@postgresql.org)
> To make changes to your subscription:
> http://www.postgresql.org/mailpref/pgsql-jdbc


Re: Atomic operations?

From
Oliver Jowett
Date:
Dave Cramer wrote:
>
> On 18-Mar-08, at 9:40 AM, Paul Tomblin wrote:

>>   PreparedStatement ps = conn.prepareStatement(
>>      "DELETE FROM venue WHERE venueid = ? ; INSERT INTO VENUE
>> (venueid, .... ) VALUES(?, ?, ?, ?)");

>> Does that work?  Will that be atomic so that nobody else can insert
>> one with that venueid in between the delete and the insert?
>>
> I don't think so,

Actually it's fine the implicit transaction created by the server to
support autocommit wraps both queries in a single transaction and does
not commit/rollback until the end of the second query.

-O


Re: Atomic operations?

From
Dave Cramer
Date:
On 18-Mar-08, at 7:18 PM, Oliver Jowett wrote:

> Dave Cramer wrote:
>> On 18-Mar-08, at 9:40 AM, Paul Tomblin wrote:
>
>>>  PreparedStatement ps = conn.prepareStatement(
>>>     "DELETE FROM venue WHERE venueid = ? ; INSERT INTO VENUE
>>> (venueid, .... ) VALUES(?, ?, ?, ?)");
>
>>> Does that work?  Will that be atomic so that nobody else can insert
>>> one with that venueid in between the delete and the insert?
>>>
>> I don't think so,
>
> Actually it's fine the implicit transaction created by the server to
> support autocommit wraps both queries in a single transaction and
> does not commit/rollback until the end of the second query.
>
Yeah, using v3 protocol this is presented as one prepare/execute.
Thanks for catching that.
> -O
>
>
> --
> Sent via pgsql-jdbc mailing list (pgsql-jdbc@postgresql.org)
> To make changes to your subscription:
> http://www.postgresql.org/mailpref/pgsql-jdbc


Re: Atomic operations?

From
Kris Jurka
Date:

On Wed, 19 Mar 2008, Dave Cramer wrote:

>
> On 18-Mar-08, at 7:18 PM, Oliver Jowett wrote:
>
>> Actually it's fine the implicit transaction created by the server to
>> support autocommit wraps both queries in a single transaction and does not
>> commit/rollback until the end of the second query.
>>
> Yeah, using v3 protocol this is presented as one prepare/execute. Thanks for
> catching that.

For the record, v2 sends both statements in a single query message
grouping them in the same transaction.  v3 sends a prepare and execute for
each statement (as required by the extended query protocol), but the
transaction is demarcated by the Sync message and there's only one of
those.

Kris Jurka