From: | Peter Mount <peter(at)retep(dot)org(dot)uk> |
---|---|
To: | Mark Dzmura <mdz(at)digital-mission(dot)com> |
Cc: | "pgsql-interfaces(at)postgreSQL(dot)org" <pgsql-interfaces(at)postgresql(dot)org> |
Subject: | Re: JDBC squirrely transaction behavior?? |
Date: | 2000-06-05 10:03:43 |
Message-ID: | Pine.LNX.4.10.10006051051080.5726-100000@maidast.retep.org.uk |
Views: | Raw Message | Whole Thread | Download mbox | Resend email |
Thread: | |
Lists: | pgsql-interfaces |
On Wed, 31 May 2000, Mark Dzmura wrote:
> dumb JDBC/SQL question:
>
> I have just moved some code over from pg 6.5.2 to pg 7.0 and am starting to modify an existing code base
> to use transactions.
>
> I need to add some records to masterfile tables in a particular order (due to foreign key dependencies) and
> want to use a transaction to allow aborting the whole shebang in the event any of the inserts fails.
>
> Below is a simple sample of code which shows the problem.
>
> ---------------------------------------------
>
> create table foos (foo_id serial primary key, foo_name varchar(64) unique);
>
> create table bars(bar_id serial primary key, foo_id int4 references foos, bar_len int4, bar_width int4);
>
> ...
>
> connection.setAutoCommit(false);
>
> while (true)
> {
> try
> {
> try
> {
> insert into foos (foo_name) values ('foo test value #1');
> }
> catch (SQLException e)
> {
> system.out.println("attempt to insert duplicate foo ... not a problem.");
> }
> // get the foo_id for this foo;
> rs = select foo_id from foos where foo_name='foo test value #1');
> if (rs.next()
> {
> int foo_id = rs.getInt(1);
> insert into bars (foo_id, bar_len, bar_width) values (foo_id, 25, 99);
> connection.Commit();
> }
> else
> {
> connection.Rollback();
> System.out.println("error: unable to lookup foo_id");
> throw new Exception("internal error...");
> }
> }
> catch (SQLException e)
> {
> System.out.println("bad things a-happenin");
> e.printStackTrace();
> }
> }
>
> This code will run for a number of insertions, then fail because the
> select of the foo_id returns no records. This should be impossible,
> because either (1) the foo_id was just added to the foos table, or (2)
> it had previously been added. Either way, there should be a record
> with a matching namefield.
I can see a problem here. Your first insert inserts foo_id, and fails if
foo_id already exists. In your code, you ignore this which is fine outside
a Transaction. However, because you are using a transaction, the
transaction is now in a failed state, so everything else done in that
transaction will be ignored.
So, I'd add in the catch clause of that block a connection.rollback()
call. That should then start a new transaction, which will then work for
the rest of the code.
The alternative is to but a connection.commit() after the insert, which
may work in this case, but you have to think about the integrity of your
tables.
> I then commented out the transaction stuff, and verified that the code ran properly.
>
> My first thought was that statement #2 was unable to see changes effected by
> statement #1, but because they are within the scope of the same transaction,
> they should be able to....strangely, this works for some records, but not others.
>
> Is the pg or jdbc support for transactions broken??
No, this looks like normal behaviour. Because foo_id already exists, the
first insert fails, and marks that transaction as void. PG will ignore
everything until the transaction ends, rolls back, or autocommit is
enabled.
> Finally, the API does not seem to offer support for nested transactions, which
> sometime come in handy... But even the JavaSoft-approved JDBC book
> written by the authors of JDBC does a lame job of covering transactions
> (and many other things...)
This is because Postgres doesn't support nested transactions. There's a
lot of JDBC internals that could be implemented easier if we had nested
transactions.
> Any guesses as to when the postgresql jdbc driver will support the JDBC 2.x extensions
> for record insert/update/delete via the special record in a result set ??
Possibly 7.1. It depends on if I get time between now and then. Time may
be tight for the next couple of months, as I may be moving home shortly,
and obviously I'll need to give that some priority ;-)
Peter
--
Peter T Mount peter(at)retep(dot)org(dot)uk
Main Homepage: http://www.retep.org.uk
PostgreSQL JDBC Faq: http://www.retep.org.uk/postgres
Java PDF Generator: http://www.retep.org.uk/pdf
From | Date | Subject | |
---|---|---|---|
Next Message | Peter Mount | 2000-06-05 10:31:02 | Re: Re: Simple bug in JDBC interface |
Previous Message | Peter Mount | 2000-06-05 09:47:21 | Re: PostgreSQL JDBC error: Missing or erroneous pg_hba.conf file |