Hi,
so now, the problem is how to safely reuse a transaction that has
already been started when an operation is started inside another one. A
good use case is :
private void recursivelyDelete( Dn dn ) throws Exception
{
EntryCursor results = connection.search( dn, "(objectClass=*)",
SearchScope.ONELEVEL, "*" );
while ( results.next() )
{
Entry result = results.get();
Dn childDn = result.getDn();
recursivelyDelete( childDn );
}
results.close();
connection.delete( dn );
}
Here, we should be able to do a search inside a search (currently it's
failing) and also a delete inside a search.
There are two options, as Selcuk said :
- we can create a new txn for each new operation, and keep them within
the cursor
- or we can reuse the existing txn
(if I correctly express Selcuk's vision. Feel free to correct me).
AFAIU, there is some check that need to be modified in the
beginTransaction() code to allow a new transaction to be started. First
of all, the txn must not anymore be stored as a ThreadLocal variable.
Second, the operationContext should store the txn.
The second option needs a counter which will be incremented for each new
usage, and decremented when we commit the txn.
The issue with this approach, AFAICS, is that when the txn is aborted,
we have to see if we should revert everything, and the second issue is
that when we are reusing a readOnly txn, to do a write, then the txn has
to be promoted to a write txn.
All in all, I don't see a simple way to deal with the two issues I
mentioned if we want to reuse the txn. IMO, I do think that creating a
new txn is probably a better solution. However, we may be able to reuse
a ReadOnly txn when starting a new ReadOnly txn. In this case, we can
add a ref counter, and an abort could simply do nothing if the ref
counter is not 0.
Does it makes sense ?
--
Regards,
Cordialement,
Emmanuel Lécharny
www.iktek.com