Re: Transaction atomicity

From: Dave Cramer <pg(at)fastcrypt(dot)com>
To: Giuseppe Sacco <giuseppe(at)eppesuigoccas(dot)homedns(dot)org>
Cc: pgsql-jdbc(at)postgresql(dot)org
Subject: Re: Transaction atomicity
Date: 2007-03-07 12:15:07
Message-ID: C71D4FFF-944B-4786-8A56-FC0236782B40@fastcrypt.com
Views: Raw Message | Whole Thread | Download mbox | Resend email
Thread:
Lists: pgsql-jdbc

Giuseppe

Couple of things.

1) What you are observing is quite normal for postgresql. It use MVCC
so it's quite possible for every connection to see the same value for
max (seNR).
which leads us to 2

2) Don't use max() for this. If you have to use max then you have to
lock the record before doing the insert which will slow everyone
down. Postgresql provides you with sequences for exactly this
purpose. Use nextval('sequence_name') to increment it and currval
('sequence_name') to get the value that your connection just used.

I strongly suggest you read and understand the section on MVCC in the
postgresql manual and sequences.

Dave
On 7-Mar-07, at 6:59 AM, Giuseppe Sacco wrote:

> Hi all,
> I have a question about a simple code that should automatically
> insert a
> record in a table. The primary key for this record is automatically
> generated during the INSERT statement, as the max value plus one.
>
> The (simplified, since the real number of fields is 5) code is:
>
> final String query = "INTO table (docId,seqNr) " +
> "VALUES (?, (SELECT 1 + coalesce (max(seqNr), 0) "+
> "FROM table " +
> "WHERE seqNr BETWEEN 0 AND (9223372036854775807-1) ))";
> Connection conn=daof.getConnection();
> try {
> conn.setAutoCommit(true);
> PrepararedStatemen st = conn.prepareStatement(query);
> st.setString(1,'myDocId');
> st.executeUpdate();
> conn.close();
> }
> catch (SQLException e) {
> try { conn.close(); } catch (SQLException ee) {}
> throw e;
> }
>
> I then create Runtime.getRuntime().availableProcessors() threads that
> create a DataSource and start executing that code in parallel. What
> happens is that I get many DUPLICATE KEY errors. I thought that in
> AutoCommit all insert are supposed to be serialized, so they should
> create a seqNr different since MAX(seqNr) is different at each call.
>
> Is my reasoning correct? Or is it a different problem, maybe with jdbc
> or postgresql?
>
> Thanks,
> Giuseppe
>
> ---------------------------(end of
> broadcast)---------------------------
> TIP 4: Have you searched our list archives?
>
> http://archives.postgresql.org
>

In response to

Responses

Browse pgsql-jdbc by date

  From Date Subject
Next Message Andres Olarte 2007-03-07 14:36:32 Re: LISTEN question
Previous Message Giuseppe Sacco 2007-03-07 11:59:12 Transaction atomicity