Daniel John Debrunner wrote:
Lance J. Andersen wrote:
Daniel John Debrunner wrote:
Somewhere in the JDBC specs/api/tutorial it says that JDBC drivers
should throw SQLExceptions rather than generic exceptions. Thus a
SQLException is preferred to a NullPointerException.
[I can't find that text now, though :-(]
That is correct where possible a SQLException is the correct error. You
can set it cause, starting in JDBC 4 to the real culprit.
For out of memory exceptions, this causes somewhat of a problem. I have
code that fails gracefully if an OutOfMemoryException is thrown during
establishment of a connection. The issue is that trying to create the
new SQLException will fail due to an OutOfMemoryException. :-(
Not sure you want to jump through hoops for an OutOfMemoryException, i
do not think it is worth it.
But I do :-). We are seeing several cases where users of Derby are
seeing OutOfMemoryExceptions, not because of memory leaks, just because
Derby is allocating too much memory. An easy to use database would
recover gracefully from this, and allow continued operation as best as
possible.
http://issues.apache.org/jira/browse/DERBY-443
One work-around is to pre-allocate a static singleton SQLException for
this out of memory case, there are two problems with this:
- The original OutOfMemoryException cannot be chained to the singleton,
thus some useful information is lost (the original stack trace).
- Looking forward, there would need to be several (many?) singleton
SQLExceptions, for example the one I'm experimenting with has a SQLState
starting with 08 indicating a connection failure. E.g. an
OutOfMemoryException during an executeQuery would need a SQLException
with a different SQLState.
The other alternative is to directly throw the OutOfMemoryException as
this requires no new object allocation. The problem with this is that it
is less natural for applications, which will be catching SQLException
but most likely not OutOfMemoryExceptions. And it removes the
possibility of using the JDBC SQLException sub-classing to indicate that
the operation is re-tryable.
Maybe there's also the option of trying to allocate a new SQLException
and if that fails revert to using the singleton, or throwing the
original OutOfMemoryException.
If you are out of memory, will there ever be a chance to create a new
SQLException object?
Yes, the process of throwing an exception can catching it further up the
stack will allow objects to be garbage collected that were only
referened from local variables. A simple example,
byte[] A1= new byte[10000];
byte[] A2= new byte[30000];
If the OutOfMemoryException is thrown allocating A2, and caught further
up the stack (as happens with the JDBC driver], then the memory for A1
can be collected.
Assuming the GC has had time to run. So I guess you can do what you
suggest, try and create a new SQLException and if not punt and throw
the OutOfMemoryException.
I am not fond of a Singleton of a SQLException but that is just me.
Or even simpler, if I try to allocate 1Mb and fail, there is probably
still enough memory to allocate a SQLException.
Thanks,
Dan.
|
- Re: SQLExceptions and OutOfMemoryExceptions Lance J. Andersen
-