
Hi, ----- Original Message ----- From: <strasser@uni-bremen.de> To: "vicente.botet" <vicente.botet@wanadoo.fr> Sent: Saturday, March 06, 2010 3:09 PM Subject: Re: [boost] [transact] transaction language macros (was: Re: [transact] code in sandbox)
Zitat von "vicente.botet" <vicente.botet@wanadoo.fr>:
Zitat von "vicente.botet" <vicente.botet@wanadoo.fr>:
I agree this doesn't means that the transaction can not be removed shortly thereafter, but neither the oposite, that is that the transaction will be destructed shortly thereafter. The transaction could be reused if the implementation is improved. I have already, as I showed in a previous mail, moved the transaction declaration out of the try, so the transaction out leaves the retry, and the internal loop.
I think there is another problem with the restart-approach, unless the following use case should be invalid:
transaction{ ... }retry{ transaction{ ... } throw 1; }
with the current approach, inside the retry-clause there is a current transaction which is not active. the second transaction-scope tries to create a nested transaction of the inactive transaction - and throws no_active_transaction.
is it a valid use case to run a transaction inside a retry-clause?
retry blocks should be quite simple, modify some local variables, update some policies on the current transactions and so on. In principle this should not need a transaction to achieve its purpose. Have you find a use case that needs a transaction?
I think so:
tx::numeric<int> nr_of_retries=0;
void thread_start(){ //start of multiple threadsx
transaction{ ... }retry{
transaction{ ++nr_of_retries; }
}
}
What is the goal of increassing a shared variable nr_of_retries on the retry block, statistics? I thought you were looking for a real use case, for which we need a transaction on the retry block to avoid starvation. I will add that the schema is recursive without an end transaction{ ... } retry { transaction{++nr_of_retries;} retry { transaction{++nr_of_retries;} retry { transaction{++nr_of_retries;} retry { ... } } } } This why I said that it is not a good principle to repare something that fails using the same failing technique.
yes, you could achieve the same thing by counting nr_of_retries locally and adding it once the transaction has succeeded, but my point is not that this use case is absolutely necessary, but that I can't find a good reason to prohibit it.
I don't dsee any propblem to prohibit a construction that does not have real use cases.
if I'd see see the above code without reading any documentation, I'd expect that the transaction inside the retry block starts another root transaction. and in fact, that was the behaviour until we decided that the transaction should be accessible in the retry-clause and be restarted after it.
The fact the preceding approach allows this construction is not an hint it was supperior approach, as I don't see yet the need to allow the construction. I agree however that if we need to allow this, the transaction should be a root transaction otherwise the transaction effect cound not influence the behaviour of the other transactions. IMO the retry block should access local variables, thread specific variables or transaction specific functions.
if not, why not?
Well, I would say that it is not a good principle to repare something that fails using the same failing technique. The problem a 'nested' transaction on a non active transaction introduce is the visibility of the 'nested' transaction.
I'd expect it to be a root transaction, similar to:
try{ transaction tx;
tx.commit(); }catch(isolation_exception &){ transaction tx; ... tx.commit(); }
while the current behvaiour is:
transaction tx; try{ ... tx.commit(); }catch(isolation_exception &){ transaction tx; ... tx.commit(); }
when you see the macro-code above, would you expect it to behave like the second version?
For the moment I expect it will fail, and this can only be provided in the second case.
on a seperate note, I noticed that .NET has a namespace System.Transactions which seems to be quite similar to what we're trying to achieve with Boost.Transact. on first sight there isn't much to learn from, but maybe one of us should have a closer look.
Could you give some pointers? Thanks, Vicente