directory-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Selcuk AYA <>
Subject Re: Storing the txn nto each operationContext
Date Sun, 25 Dec 2011 19:27:05 GMT
On Sun, Dec 25, 2011 at 8:08 PM, Emmanuel Lécharny <> wrote:
> On 12/25/11 5:58 PM, Selcuk AYA wrote:
>> On Sun, Dec 25, 2011 at 5:37 PM, Emmanuel Lecharny<>
>>  wrote:
>>> Hi,
>>> I started to play with this concept. The idea is to able to have
>>> encapsulated operations using their own transactions, following these
>>> rules
>>> :
>>> 1) if there is another pending Read transaction, and if the new operation
>>> is
>>> read only, then reuse the pending transaction
>>> 2) if there is another pending Read transaction, and if the new operation
>>> is
>>> ReadWrite, then create a new transaction
>>> 3) if there is another ReadWrite transaction, then generate an error (we
>>> can't have such a case)
>>> That means we can have a non limited number of encapsulated RO txns, but
>>> we
>>> can't have more than one RW txn running.
>>> RO(RO(RO...(RO)...))) is possible
>>> RO(RO(RW))) is possible
>>> RO(RO(RW(RO is not possible
>>> RW(RO is not possible
>>> RW(RW is not possible
>>> In order to implement that, we need to add one thing :
>>> - a nbRef in readOnly transactions, which will be incremented and
>>> decremented as soon as we add new RO txns or abort/commit txns
>>> Is that enough ?
>> this is also a reply to you previous email.
>> I suggest we use a txn per operation but we do not have to store the
>> txn context pointer in operation context. We can still have the thread
>> context stored in thread local variable but we also store a TxnHandle
>> ref in EntryFilteringCursor. And we do something like this:
>> next()
>> {
>>   get txn handle stored in the cursor and set it as the thread local
>> variable.
>> do the next
>> unset the thread local variable.
>> }
> In fact, as each operation except Search are atomic, I don't know if it's
> useful to store the txn in the thread local variable. Regarding the search,
> we just have to store the txn in the cursor, so we don't have to store it
> into the thread local variable either.
> Another reason we might not want to use thread local variable is that an
> abandon operation will have to close a txn, and that means grab the txn from
> another thread.It's easier to get the existing cursor, and close the cursor.
> (FYI, we may have more than one thread per session, just in order to be able
> to handle an AbandonRequest)
> Unless I'm missing something, of course !

There are different layers and different classes that call into txn
layer and txn layer conveniently gets the current txn from the thread
local variable. If you change this you will have to pass around txn
context. Not impossible but quite a number of changes.

But AbondonRequest is really a problem. I see that the abandon request
listener for search just closes the cursor but at that time the txn
might be executing and we cannot just abort an executing txn. I have a
question about abandonable requests in general. How do you handle
freeing resources related to Requests in a clean way? As far as I know
similar situations are usually handled like this: Lets say we have a
Disk and we want to close it because of a request received from a side
channel. Then normal user threads do this:

grab disk from a common table increment ref count
check if disk is closed and return an error if it is.
grab resources
use disk
decrement ref count

When close request from the side channel is received:
remove disk from global table
mark it as closed
wait until ref count drops to zero
then free resources and delete disk.

So resources are freed only after we make sure no user uses them.
Currently, is there a way to close the cursor only after making sure
that no thread will use the cursor to do search? We can abort the txn
related to the cursor only after making sure that no thread is
executing it.

>> Lets say an embedded app developer does something like this:
>> {
>> open cursor1
>> while ( next on cursor1 ).
>>   for some certain entry do a delete
>> open cursor2
>> do a search on cursor2.
>> close cursor1
>> close cursor2
>> }
>> if we do something like suggested above, then consistency semantics is
>> clear: each cursor sees the world as of the time it is opened. So
>> cursor1 does not get affected by the delete and cursor2 sees the
>> delete. This implementation does not use txn reuse.
>> If we deal with reusing the txn contexts and hence ref counts,
>> depending on where you close the cursor, what cursor2 see will change.
>> As I understand your suggestion, in the above scenario, delete uses
>> its own txn and cursor2 reuses cursor1's txn. So cursor2 wont see the
>> delete as it see the world as of cursor1's opening time. But if
>> cursor1 is closed before opening the cursor2, then cursor2 will see
>> the delete. For a developer,  such things make reasoning with
>> consistency  I think.
> I'm not sure I get what you wrote at the end of your second paragraph ("For
> a developer, such things make reasoning with consistency I think."). But I
> think that opening a second cursor inside a first one should simply leads to
> processing the same data, even if some entries have been deleted in the mean
> time.

I am simply saying what kind of data  a cursor  sees should not depend
on when you close the cursor or whether there is another cursor
already open when you open a  cursor.

> --
> Regards,
> Cordialement,
> Emmanuel Lécharny

View raw message