db-derby-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Suresh Thalamati <suresh.thalam...@gmail.com>
Subject Re: regarding semantics of select in Autocommit mode .. ( and derby 265)
Date Mon, 23 May 2005 21:51:47 GMT
catching runtime exception like NPE,  will  report a wrong error if 
there is
a real bug in the code at a later point in time.  Unless there is a  
real difference
in performance , I think it is better to do checks to make sure that NPE 
does not


Mike Matrigali wrote:

> I think your description below is valid.  Blob's are not valid after the
> transaction that opened them commits.  Doing interleaved result sets in
> autocommit mode is almost always a bug waiting to happen.  "Held"
> cursors help some, but still after the commit you must do a next - the
> current blob is not valid.
> A NPE is not a good error, but if possible I would like to see the
> catch of the error condition pushed as high up in the code as possible.
> Is it possible for the jdbc getBlob() call to recognize that the
> transaction of the blob has closed?  If not then maybe at least the
> catch can be placed in the blob datatype itself, it may just have to
> check every time it accesses store to get the next piece of the blob -
> or better performing would be to assume the point is good and have
> a try/catch to catch the error and turn it into a more reasonable
> user level error.
> Sunitha Kambhampati wrote:
>> I am actually looking at Derby 265 (an assert failure in store).  The 
>> assert failure occurs on a getBlob call which is because at that time 
>> there is no transaction context.  But then, looking at the repro got 
>> me thinking about select stmt in autocommit mode and also wonder if 
>> the repro is testing the right behavior or not..
>> Section 10.1 of the JDBC 3.0 spec says
>> Enabling autocommit,  causes the jdbc driver to do a transaction 
>> commit after each individual sql statement as soon as it is 
>> complete.  the point at which it is complete depends on type of 
>> statement.  for select statement  :- statement is complete when 
>> resultset is closed and result set is closed* as soon as one* of the 
>> following happens
>>   -- all rows have been retrieved
>>  -- associated statement object is re-executed
>>  -- another Statement object is executed on the same connection
>> from repro in  Derby-265 :
>> Note s, s2 are on the same connection object that is in  autocommit mode
>> 1    s.execute("select * from maps")
>> 2    rs1 = s.getResultSet();
>> 3    s2.execute("select * from maps")        4    rs2 = 
>> s2.getResultSet();                    5    rs2.next();
>> 6    rs2.getBlob(6);
>> 7    rs1.close();
>> 8    rs2.next();
>> 9    rs2.getBlob(6);           __________________
>> -- from the spec (10.1) , does it mean that the statement execution 
>> on line 3 would commit the earlier statement on #1.   ? If so, we 
>> dont seem to do that.
>> -- Also, rs1.close() is internally calling a commit but the 
>> connection is actually dealing with s2 currently and  so is it right 
>> that rs1.close() commits the transaction associated with s2 ?   Then 
>> again, is this interleaving of reading of resultsets and select 
>> statement even valid ? . I checked the jdbc spec and the api and also 
>> briefly the tutorial book but didnt come across much about this. .
>> Coming back to the reason for the assert failure
>> -- so rs1.close() is committing the transaction which is why 
>> rs2.getBlob(6) is left without a transaction context leading to the 
>> assert failure.
>> A simpler snippet for just the assert failure case (s ,s1 on one 
>> connection in autocommit mode).
>> 1    s.execute("select * from maps'");
>> 2    rs = s.getResultSet();
>> 3    s1.executeUpdate("insert ....  ");
>> 4    rs.next();
>> 5    rs.getBlob(6);
>> -- when s1 is executed , s is complete ( and committed ) per spec.  
>> Will rs still be valid at (line 4), I guess that depends on the 
>> holdability.  As rs is a hold cursor, what transaction context should 
>> this be in  ?
>> -- The assert failure happens on the getBlob call ( line 5) , which 
>> is because the blob has an underlying outputstream and uses a 
>> transaction context in this case.
>> The jdbc api for Blob says ' A blob object_ is valid for the 
>> duration* *of the transaction in which* *it was created_*'*.  From 
>> this it seems like the call on #5  is actually not valid ( since the 
>> transaction in which the blob was created is complete).
>> -- All this makes me think that the program is incorrect.  But I 
>> guess  we should be throwing  a  better user error instead of an 
>> npe/assert.
>> ___________________
>> Also some notes on derby 265.
>> -- repro violated this part of the jdbc api for Statement
>> "By default, only one |ResultSet| object per |Statement| object can 
>> be open at the same time. Therefore, if the reading of one 
>> |ResultSet| object is interleaved with the reading of another, each 
>> must have been generated by *different |Statement| objects*. All 
>> execution methods in the |Statement| interface implicitly close a 
>> statment's current |ResultSet| object if an open one exists"
>> So  made changes to use different Statement objects.
>> -- The derby 265 assert failure cause  is not specific to network 
>> server mode as such. In the original repro, getBlob()  was not being 
>> called in the program which is why embedded was not throwing the 
>> error,  but for network server a rs2.next() actually retrieves the 
>> blob (getBlob()) which causes the assert to be thrown at the store 
>> level.  So changing the program to call rs2.getBlob shows up the 
>> error in embedded mode also.
>> -- Note, the assert failure happens only if the blob column overflows
>> I'd appreciate any comments/feedback.
>> Thanks,
>> Sunitha.

View raw message