On 12/25/11 5:58 PM, Selcuk AYA wrote:
On Sun, Dec 25, 2011 at 5:37 PM, Emmanuel Lecharny<elecha...@gmail.com>  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 !


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.


--
Regards,
Cordialement,
Emmanuel Lécharny
www.iktek.com

Reply via email to