Subject | serious problem with FBResultSet |
---|---|
Author | Marczisovszky Daniel |
Post date | 2002-03-27T11:17:25Z |
Hi,
Well... Blobs again... I've been using that version of the driver that
returned FBResultSetWithFields when a query was executed.
FBResultSetWithFields cached the Blobs (Binaries, does not matter
now), so when one wanted to read it, it returned an actually
pre-fetched blob.
Now that version I got from CVS yesterday, uses FBResultSet. This does
not cache the blob values. Problem is the following: in autocommit
mode, FBStatement starts the transaction, executes the query, creates
the results, *immediately commits* the transaction and returns the
resultset. Blobs can be read only with a valid transaction, but in
autocommit mode before the first next() is called we already have no
valid transaction.
So after the user's program received the ResultSet object, there is no
valid transaction. After this, the user program tries to read from the
Blob field, but getBytes (getBinaryStream) will throw an exception in
FBBlobField, because there is no active transaction.
Solution 1.: when FBResultSet creates the FBStatement, it should set
autocommit to false, and it should close the transaction only after
the last row is fetched through FBStatementFetcher.
Possible problems with solution 1:
- if the last row is never fetched, transaction won't be closed.
- when getBlob() (not getBytes!) is called, it returns a FBBlob
object. Let's say we query for only one row. After this row is read,
the transaction will be closed, but getBinaryStream() still can be
called, and we will have the same exception as now, as there won't
be any valid transaction at that time.
Solution 2.: when getBlob is accessed in FBBlobField, it
should start a new transaction.
Possible problem with solution 2:
- How should we know when to close the transaction? With binary fields
it's not a big problem, we should close immediately after getBytes()
called, but with Blobs we have the same problem as I mentioned above
with solution 1.
Best wishes,
Daniel
Well... Blobs again... I've been using that version of the driver that
returned FBResultSetWithFields when a query was executed.
FBResultSetWithFields cached the Blobs (Binaries, does not matter
now), so when one wanted to read it, it returned an actually
pre-fetched blob.
Now that version I got from CVS yesterday, uses FBResultSet. This does
not cache the blob values. Problem is the following: in autocommit
mode, FBStatement starts the transaction, executes the query, creates
the results, *immediately commits* the transaction and returns the
resultset. Blobs can be read only with a valid transaction, but in
autocommit mode before the first next() is called we already have no
valid transaction.
So after the user's program received the ResultSet object, there is no
valid transaction. After this, the user program tries to read from the
Blob field, but getBytes (getBinaryStream) will throw an exception in
FBBlobField, because there is no active transaction.
Solution 1.: when FBResultSet creates the FBStatement, it should set
autocommit to false, and it should close the transaction only after
the last row is fetched through FBStatementFetcher.
Possible problems with solution 1:
- if the last row is never fetched, transaction won't be closed.
- when getBlob() (not getBytes!) is called, it returns a FBBlob
object. Let's say we query for only one row. After this row is read,
the transaction will be closed, but getBinaryStream() still can be
called, and we will have the same exception as now, as there won't
be any valid transaction at that time.
Solution 2.: when getBlob is accessed in FBBlobField, it
should start a new transaction.
Possible problem with solution 2:
- How should we know when to close the transaction? With binary fields
it's not a big problem, we should close immediately after getBytes()
called, but with Blobs we have the same problem as I mentioned above
with solution 1.
Best wishes,
Daniel