Обсуждение: connection/statement becomes unstable following SQLException

Поиск
Список
Период
Сортировка

connection/statement becomes unstable following SQLException

От
Rob Prowel
Дата:
consider the following:

table lookup_industry(industry varchar(20) not null
unique);

and the following code:

------------------------------------------------------------
public static void main(String [] arg) {

        lookupIndustry conn=new lookupIndustry();
        try {
                conn=new lookupIndustry((new
jobDBconnection()).conn); }
        catch(Exception e) {
                System.exit(1); }
                // connect to the db

        System.out.println("---------------------");
        for (int i=0; i<arg.length; i++) {
                try {
                        System.out.println("adding
industry("+arg[i]+")");
                        conn.addIndustryList(arg[i]);
}
                        // attempt to add a new record
                catch (Exception e) {

System.out.println(arg[i]+":"+Integer.toString(i)+
                                " "+e.toString()); }
                finally {
System.out.println("try>"+Integer.toString(i)); }

System.out.println("loop>"+Integer.toString(i));
                }
                // should add new records and print
alerts for each record that
                // already exists

        System.out.println("---------------------");
        System.exit(0);
        }

--------------------------------------------------------------------

And the following output:

$ jdbcrun the geese fly high
---------------------
adding industry(the)
the:0 java.sql.SQLException: ERROR:  Cannot insert a
duplicate key into unique index
lookup_industry_industry_key

try>0
loop>0
adding industry(geese)
insert rv=1
try>1
loop>1
adding industry(fly)
fly:2 java.sql.SQLException: ERROR:  Cannot insert a
duplicate key into unique index
lookup_industry_industry_key

try>2
loop>2
adding industry(high)
insert rv=1
try>3
loop>3
---------------------

----------------------------------------------------

notice that the only two iterations that generate an
exception are the first and thrid ones...even though
(the,geese,fly,high) are already in the database and
the values are constrained to be unique in the table
definition.

It seems that there is a bug in the Connection or
Statement logic in the JDBC driver that isn't
resetting things immediately after an exception
occurs.

I have one Connection open and addIndustryList()
creates a new Statement object for every insert that
it does to the table.  If the entry already exists in
the table then addIndustryList() throws an
SQLException object that I SHOULD be able to catch and
ignore, just moving on to add the next record.  Only
other thing I should mention is that I turn autocommit
off and commit each transaction as it is entered.

I believe I've uncovered a bug and would like someone
who owns or is very familiar with the code to reply.
I can then send them more information such as my
complete classes and the psql script to create the
table in question.

Finally, here's my platform information:

i586 Linux 2.4.21
PostgreSQL 7.2.1
pgjdbc3.jar
J2SE 1.4.2

Thanks.





__________________________________
Do you Yahoo!?
Yahoo! Calendar - Free online calendar with sync to Outlook(TM).
http://calendar.yahoo.com

Re: connection/statement becomes unstable following SQLException

От
Dave Tenny
Дата:
I guess the most obvious question is do you call Connection.rollback() after
the failed statement?  It would be helpful to see the transaction
context code.

Rob Prowel wrote:

>consider the following:
>
>table lookup_industry(industry varchar(20) not null
>unique);
>
>and the following code:
>
>------------------------------------------------------------
>public static void main(String [] arg) {
>
>        lookupIndustry conn=new lookupIndustry();
>        try {
>                conn=new lookupIndustry((new
>jobDBconnection()).conn); }
>        catch(Exception e) {
>                System.exit(1); }
>                // connect to the db
>
>        System.out.println("---------------------");
>        for (int i=0; i<arg.length; i++) {
>                try {
>                        System.out.println("adding
>industry("+arg[i]+")");
>                        conn.addIndustryList(arg[i]);
>}
>                        // attempt to add a new record
>                catch (Exception e) {
>
>System.out.println(arg[i]+":"+Integer.toString(i)+
>                                " "+e.toString()); }
>                finally {
>System.out.println("try>"+Integer.toString(i)); }
>
>System.out.println("loop>"+Integer.toString(i));
>                }
>                // should add new records and print
>alerts for each record that
>                // already exists
>
>        System.out.println("---------------------");
>        System.exit(0);
>        }
>
>--------------------------------------------------------------------
>
>And the following output:
>
>$ jdbcrun the geese fly high
>---------------------
>adding industry(the)
>the:0 java.sql.SQLException: ERROR:  Cannot insert a
>duplicate key into unique index
>lookup_industry_industry_key
>
>try>0
>loop>0
>adding industry(geese)
>insert rv=1
>try>1
>loop>1
>adding industry(fly)
>fly:2 java.sql.SQLException: ERROR:  Cannot insert a
>duplicate key into unique index
>lookup_industry_industry_key
>
>try>2
>loop>2
>adding industry(high)
>insert rv=1
>try>3
>loop>3
>---------------------
>
>----------------------------------------------------
>
>notice that the only two iterations that generate an
>exception are the first and thrid ones...even though
>(the,geese,fly,high) are already in the database and
>the values are constrained to be unique in the table
>definition.
>
>It seems that there is a bug in the Connection or
>Statement logic in the JDBC driver that isn't
>resetting things immediately after an exception
>occurs.
>
>I have one Connection open and addIndustryList()
>creates a new Statement object for every insert that
>it does to the table.  If the entry already exists in
>the table then addIndustryList() throws an
>SQLException object that I SHOULD be able to catch and
>ignore, just moving on to add the next record.  Only
>other thing I should mention is that I turn autocommit
>off and commit each transaction as it is entered.
>
>I believe I've uncovered a bug and would like someone
>who owns or is very familiar with the code to reply.
>I can then send them more information such as my
>complete classes and the psql script to create the
>table in question.
>
>Finally, here's my platform information:
>
>i586 Linux 2.4.21
>PostgreSQL 7.2.1
>pgjdbc3.jar
>J2SE 1.4.2
>
>Thanks.
>
>
>
>
>
>__________________________________
>Do you Yahoo!?
>Yahoo! Calendar - Free online calendar with sync to Outlook(TM).
>http://calendar.yahoo.com
>
>---------------------------(end of broadcast)---------------------------
>TIP 9: the planner will ignore your desire to choose an index scan if your
>      joining column's datatypes do not match
>
>
>


Re: connection/statement becomes unstable following SQLException

От
Barry Lind
Дата:
Rob,

There are a couple of things going on here.  First is the way postgres
works.  One postgres gets an error, all subsequent sql statements issued
  in that transaction will also error.  So to get things back to a
normal state you need to rollback the transaction after any error
occurs.  So in general in postgres you can't trap an error and continue
processing without first rolling back the transaction that errored.

Also what version of the driver and database are you using?  Have you
tried the latest version from the jdbc.postgresql.org website?

Finally, if you turned sql statement tracing on on the server you would
be able to see exactly what was going on by looking at the server log files.

This may be a jdbc driver bug, but it also could be a number of other
things as well.

thanks,
--Barry



Rob Prowel wrote:
> consider the following:
>
> table lookup_industry(industry varchar(20) not null
> unique);
>
> and the following code:
>
> ------------------------------------------------------------
> public static void main(String [] arg) {
>
>         lookupIndustry conn=new lookupIndustry();
>         try {
>                 conn=new lookupIndustry((new
> jobDBconnection()).conn); }
>         catch(Exception e) {
>                 System.exit(1); }
>                 // connect to the db
>
>         System.out.println("---------------------");
>         for (int i=0; i<arg.length; i++) {
>                 try {
>                         System.out.println("adding
> industry("+arg[i]+")");
>                         conn.addIndustryList(arg[i]);
> }
>                         // attempt to add a new record
>                 catch (Exception e) {
>
> System.out.println(arg[i]+":"+Integer.toString(i)+
>                                 " "+e.toString()); }
>                 finally {
> System.out.println("try>"+Integer.toString(i)); }
>
> System.out.println("loop>"+Integer.toString(i));
>                 }
>                 // should add new records and print
> alerts for each record that
>                 // already exists
>
>         System.out.println("---------------------");
>         System.exit(0);
>         }
>
> --------------------------------------------------------------------
>
> And the following output:
>
> $ jdbcrun the geese fly high
> ---------------------
> adding industry(the)
> the:0 java.sql.SQLException: ERROR:  Cannot insert a
> duplicate key into unique index
> lookup_industry_industry_key
>
> try>0
> loop>0
> adding industry(geese)
> insert rv=1
> try>1
> loop>1
> adding industry(fly)
> fly:2 java.sql.SQLException: ERROR:  Cannot insert a
> duplicate key into unique index
> lookup_industry_industry_key
>
> try>2
> loop>2
> adding industry(high)
> insert rv=1
> try>3
> loop>3
> ---------------------
>
> ----------------------------------------------------
>
> notice that the only two iterations that generate an
> exception are the first and thrid ones...even though
> (the,geese,fly,high) are already in the database and
> the values are constrained to be unique in the table
> definition.
>
> It seems that there is a bug in the Connection or
> Statement logic in the JDBC driver that isn't
> resetting things immediately after an exception
> occurs.
>
> I have one Connection open and addIndustryList()
> creates a new Statement object for every insert that
> it does to the table.  If the entry already exists in
> the table then addIndustryList() throws an
> SQLException object that I SHOULD be able to catch and
> ignore, just moving on to add the next record.  Only
> other thing I should mention is that I turn autocommit
> off and commit each transaction as it is entered.
>
> I believe I've uncovered a bug and would like someone
> who owns or is very familiar with the code to reply.
> I can then send them more information such as my
> complete classes and the psql script to create the
> table in question.
>
> Finally, here's my platform information:
>
> i586 Linux 2.4.21
> PostgreSQL 7.2.1
> pgjdbc3.jar
> J2SE 1.4.2
>
> Thanks.
>
>
>
>
>
> __________________________________
> Do you Yahoo!?
> Yahoo! Calendar - Free online calendar with sync to Outlook(TM).
> http://calendar.yahoo.com
>
> ---------------------------(end of broadcast)---------------------------
> TIP 9: the planner will ignore your desire to choose an index scan if your
>       joining column's datatypes do not match
>




Re: connection/statement becomes unstable following SQLException

От
Rob Prowel
Дата:
--- Barry Lind <blind@xythos.com> wrote:
> Rob,
>
> There are a couple of things going on here.  First
> is the way postgres
> works.  One postgres gets an error, all subsequent
> sql statements issued
>   in that transaction will also error.  So to get
> things back to a
> normal state you need to rollback the transaction
> after any error
> occurs.  So in general in postgres you can't trap an
> error and continue
> processing without first rolling back the
> transaction that errored.
>
> Also what version of the driver and database are you
> using?  Have you
> tried the latest version from the
> jdbc.postgresql.org website?
>
> Finally, if you turned sql statement tracing on on
> the server you would
> be able to see exactly what was going on by looking
> at the server log files.
>
> This may be a jdbc driver bug, but it also could be
> a number of other
> things as well.
>


Thank you.  This problem was in fact caused by not
doing a rollback to recover from an "Excepted"
transaction.  Silly me.  I figured that if the
transaction was atomic, then the rollback would be
implicit when if the transaction failed   But after
considering that a single insert into an indexed table
cannot be "atomic", I now see the error of my ways.

Thanks to all who responded.

-Rob




__________________________________
Do you Yahoo!?
Yahoo! Calendar - Free online calendar with sync to Outlook(TM).
http://calendar.yahoo.com