Subject | Re: [IBO] Strange happenings with IB_memos |
---|---|
Author | Geoff Worboys |
Post date | 2001-07-24T03:42:56Z |
Hi Paul,
Problem Summary: Two blob fields on a TIB_Cursor. Change one blob
and post the change. Change the other blob and post the change.
After this both appear to contain the same data (the most recently
changed blob). In some circumstances it can also result in "Invalid
Blob ID" exceptions.
Note: I believe you would still see the problem even if the blob
fields were on different cursors (but attached to the same
transaction).
Short Answer:
You can work around the problem by doing a refresh immediately after
performing the post. Alternatively you can simply use TIB_Query (but
setup so that is only buffers the one record by retrieving for the
specific key value). We need to wait for Jason to confirm whether
this should be considered a bug or working by design (I suspect the
latter).
Long Answer:
The problem results from a peculiarity in the way that the IB API
manages blobs. When you post changes to a record containing blobs,
the process is performed in two stages.
1. Blobs are saved to the database, in the processing returning a
unique blob identifier value (BlobID). The problem comes from the
fact that at this stage in the processing, the BlobID returned by the
API is a "temporary" identifier - it is NOT the one that will
eventually be stored on the record itself.
2. The record itself is posted to the database - including a
reference to the temporary BlobID value. The database then creates a
new permanent BlobID for given temporary blob reference and it is the
new BlobID that is stored in the database.
The symptoms that you are seeing come about because, after stage two
is completed, IB thinks that the old temporary blobid is no longer in
use - and it happily reuses it for your next blob update. Inside the
IBO record buffer this results two blobs referencing the same
temporary storage space - thus appearing to contain the same data.
The IBO buffered datasets (TIB_Query, TIBO* etc) monitor the
processing to check for temporary blobid values, and if they exist it
automatically does a fetch of the record data after posting so that it
can get the new permanent BlobID values. (Regardless of the
BufferSynchroFlag settings.)
The unbuffered datasets (TIB_Cursor) do NOT have this check. This is
probably by design. That is; TIB_Cursor is designed for maximum
performance, so Jason avoids any unnecessary overheads - such as
refreshing the record buffer automatically after posting changes.
I had thought that we may be able to create a work around by having
TIB_Cursor check the temporaryblobid flag and automatically refetch
the record before going back into edit mode. However this would not
completely resolve the issue. The temporary blob ids are created
without reference to the statement/dataset. They only use the
reference to the database and the transaction. So the problem would
exist even if the two blobs were on different cursors against the same
transaction.
AFAICT the only full "fix" would be to have TIB_Dataset (the base for
TIB_Cursor) automatically do a refetch of the record after posting -
as the buffered dataset does now. However such automation would
impact all instances of TIB_Cursor, even those where the problem does
not matter (which I think would be most instances).
The result being that I think my short answer was the best :-) Do a
refresh immediately after posting your TIB_Cursor.
HTH
Geoff Worboys
Telesis Computing
Problem Summary: Two blob fields on a TIB_Cursor. Change one blob
and post the change. Change the other blob and post the change.
After this both appear to contain the same data (the most recently
changed blob). In some circumstances it can also result in "Invalid
Blob ID" exceptions.
Note: I believe you would still see the problem even if the blob
fields were on different cursors (but attached to the same
transaction).
Short Answer:
You can work around the problem by doing a refresh immediately after
performing the post. Alternatively you can simply use TIB_Query (but
setup so that is only buffers the one record by retrieving for the
specific key value). We need to wait for Jason to confirm whether
this should be considered a bug or working by design (I suspect the
latter).
Long Answer:
The problem results from a peculiarity in the way that the IB API
manages blobs. When you post changes to a record containing blobs,
the process is performed in two stages.
1. Blobs are saved to the database, in the processing returning a
unique blob identifier value (BlobID). The problem comes from the
fact that at this stage in the processing, the BlobID returned by the
API is a "temporary" identifier - it is NOT the one that will
eventually be stored on the record itself.
2. The record itself is posted to the database - including a
reference to the temporary BlobID value. The database then creates a
new permanent BlobID for given temporary blob reference and it is the
new BlobID that is stored in the database.
The symptoms that you are seeing come about because, after stage two
is completed, IB thinks that the old temporary blobid is no longer in
use - and it happily reuses it for your next blob update. Inside the
IBO record buffer this results two blobs referencing the same
temporary storage space - thus appearing to contain the same data.
The IBO buffered datasets (TIB_Query, TIBO* etc) monitor the
processing to check for temporary blobid values, and if they exist it
automatically does a fetch of the record data after posting so that it
can get the new permanent BlobID values. (Regardless of the
BufferSynchroFlag settings.)
The unbuffered datasets (TIB_Cursor) do NOT have this check. This is
probably by design. That is; TIB_Cursor is designed for maximum
performance, so Jason avoids any unnecessary overheads - such as
refreshing the record buffer automatically after posting changes.
I had thought that we may be able to create a work around by having
TIB_Cursor check the temporaryblobid flag and automatically refetch
the record before going back into edit mode. However this would not
completely resolve the issue. The temporary blob ids are created
without reference to the statement/dataset. They only use the
reference to the database and the transaction. So the problem would
exist even if the two blobs were on different cursors against the same
transaction.
AFAICT the only full "fix" would be to have TIB_Dataset (the base for
TIB_Cursor) automatically do a refetch of the record after posting -
as the buffered dataset does now. However such automation would
impact all instances of TIB_Cursor, even those where the problem does
not matter (which I think would be most instances).
The result being that I think my short answer was the best :-) Do a
refresh immediately after posting your TIB_Cursor.
HTH
Geoff Worboys
Telesis Computing