db-derby-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Andreas Korneliussen <Andreas.Kornelius...@Sun.COM>
Subject Re: RowLocation lifetime
Date Mon, 14 Nov 2005 10:30:03 GMT
Mike Matrigali wrote:
> null pointer is a bug, please report as a separate JIRA,not sure
> what is going on.  Note that while it is convenient for testing
> purposes to use the SYSCS_UTIL.SYSCS_INPLACE_COMPRESS_TABLE
> to cause the purging, purging of rows can happen at any time
> after a delete has been committed.  The timing depends on a
> number of factors and the timing may change in the future - so
> one should assume that as soon as a row is deleted and committed
> it may be purged.
> 
> Andreas Korneliussen wrote:
> 
>> Mike Matrigali wrote:
>>
>>> From the store point of view, 3 things can happen to
>>> RowLocations in heap tables:
>>> 1) It can be deleted (requires at least TABLE IX, ROW X locking)
>>>        o internal to store it is just marked deleted
>>>        o external to store requests for any operation on
>>>          this row will fail.  Note that your cursor can
>>>          experience this no matter what locking you do, as
>>>          it is always possible for another statement in your
>>>          transaction to do the delete.
>>> 2) It can be purged (requires at least TABLE IX, ROW X locking)
>>>        o all physical evidence of the row is removed from table,
>>>          both internal and external operations on this row will
>>>          fail.  Only committed deleted rows are purged.
>>>          Note this will never happen if you have some
>>>          sort of lock on the row as the requested X lock is
>>>          always requested in a system only transaction.
>>>        o the actual RowLocation will not be reused while
>>>          at least some sort of table level intent lock is held.
>>> 3) It can be reused (requires a table level X lock)
>>>        o basically as part of a compress all rows can be shuffled
>>>          in any way.  A former RowLocation can now point to
>>>          a completely different row.
>>>
>>> So as you point out, your implementation can have serious problems
>>> with cursors held over commit.  This is why in current usage of
>>> cursors over commit the only safe thing to do is to ask for the
>>> next row location and use it.
>>>
>>> Please make sure to consider the delete/purge cases also.  One case
>>> that often causes problems is a transaction deleting a row that is
>>> locked by it's own cursor from another statement in the same connection.
>>>
>> Yes, we need to consider those cases.
>>
>> It seems that the store is capable of graciously handle that the row 
>> get deleted (i.e by its own transaction). If the transaction later 
>> tries to update the deleted row using the resultset, the store call 
>> will return false indicating that the row was not updated. The deleted 
>> row will not be purged as long as the transaction is open.
>>
>> However in read-committed/read-uncommitted mode, a row read by the 
>> cursor, can be deleted by another transaction, and then purged.
>> It seems that the store does not handle an update of a deleted+purged 
>> record.
>>
>> On our prototype impl., I get a get a NullPointerException from the 
>> store in this case.  It comes in 
>> GenericConglomerateController.replace(..)).
>>
>> I would think there are multiple ways of adressing this issue:
>>
>> 1 We could  make the store graciously handle the situation if the 
>> RowLocation points to a deleted+purged row, by returning false if the 
>> RowLocation is invalid, (and from the caller we can give an exception)
> 
> It seems like the ConglomerateController.replace() function should throw
> an exception (other than null pointer) if it is called with a 
> non-existent RowLocation, but I could be convinced returning false
> is ok.  The problem I have is that store really has no way to tell the 
> difference between a BAD RowLocation input and one which was purged.
> 

Yes, maybe the store should throw an exception if the RowLocation is 
invalid.  Seen from the user perspective, I think the update should fail 
the same way whether the row has been deleted+purged or only deleted 
Currently the function returns false if the row has been deleted.

I ran a check on all places in the code tree that the 
ConglomerateCongtroller.replace(..) method is called. I found that the 
return value is silently ignored all places, except for in the  store 
unit-tests.

This means that an updateRow() on a deleted record, would simply return 
silently (using the optimistic concurrency approach). After the 
transaction has committed, the row would remain deleted.

I will file a JIRA for the NullPointerException case.

--Andreas





Mime
View raw message