OracleBlobInputStream, IOException: Closed Connection
852692Apr 4 2011 — edited Apr 4 2011Hi,
I'm having an issue with reading from a blob stream using Oracle 10g and the ojdbc14_g driver. The stack trace is as follows:
java.io.IOException: Closed Connection
at oracle.jdbc.driver.DatabaseError.SQLToIOException(DatabaseError.java:764)
at oracle.jdbc.driver.OracleBlobInputStream.needBytes(OracleBlobInputStream.java:261)
at oracle.jdbc.driver.OracleBufferedStream.readInternal(OracleBufferedStream.java:209)
at oracle.jdbc.driver.OracleBufferedStream.read(OracleBufferedStream.java:176)
... (application code)
I'm having a hard time reproducing this problem consistently; but from what I can tell, this is what is happening:
1. Using Spring/Hibernate (and a Tomcat managed database connection pool) I am loading an entity from the database that is associated with a blob inside a read-only transaction.
2. The input stream in the blob is returned from the routine that starts and ends the transaction that is used to load the entity.
3. At some point (after the transaction has ended) while reading from the stream the IOException occurs.
The reason for doing this is so that the database connection used to load the entity can be returned to the connection pool and be used by other threads attempting to make database requests while still having the blob stream available to read from.
So, what I think is happening is that when the database connection is returned to the connection pool and then picked up by another thread, the BlobInputStream is disassociated from the underlying database connection even though it is currently being read from; then the exception occurs. I believe this is what makes the problem difficult to reproduce because it relies on the fact that some other thread has to come in and acquire the same connection that is already in use by the blob input stream before all of the data has been read from the stream.
So, I guess my questions are: is my assessment correct? and is there a way to keep a blob stream open without tying up a connection in the database connection pool? I want to take advantage of using a stream because these blobs can get fairly large, but I don't want to tie up a database connection while the stream is being read from (I admit this is a bit paradoxical). Is this even possible? To rectify this problem, I've had to read everything from the stream and put it into a byte array before the transaction has ended to ensure that the underlying database connection does not get reclaimed/reused by the connection pool.
I have tested the same application using MySQL 5 and SQL Server 2k5/2k8 and have not run into this issue. So I'm wondering if the Oracle JDBC driver is treating database connections differently with respect to whether or not a connection is considered to be "in use" or if the MySQL and SQL Server drivers are using some other connection to keep the stream alive (a connection that's not in the connection pool).
Thanks in advance!