Boost logo

Boost :

Subject: Re: [boost] [transaction] New Boost.Transactionlibraryunderdiscussion
From: Vicente Botet Escriba (vicente.botet_at_[hidden])
Date: 2010-01-21 17:56:07


Stefan Strasser-2 wrote:
>
> Zitat von "vicente.botet" <vicente.botet_at_[hidden]>:
>>>
>>> what conflict can the other resource cause if there is no nested
>>> transaction
>>> in it?
>>>
>>> global_root_tx( resource1_root_tx, resource2_root_tx)
>>> ^ ^
>>> | |
>>> | |
>>> global_nested_tx(resource1_nested_tx, none)
>>>
>>> global_nested_tx.commit():
>>> resource1_nested_tx is published into resource1_root_tx. how can this
>>> call
>>> cause a conflict in resource2?
>>
>>
>> What I want is the the commit on global_nested_tx see if this
>> transaction must be aborted due the resource2 has conflics with
>> other resources2 of transactions. No need to continue commiting N
>> nesting levels on resorce1 if resource2 has already conflicts. This
>> is maybe an optimization, but we use things like that in Boost.STM.
>
> ok, I see.
> consider the following example:
>
> transaction roottx;
>
> //modify res1
> //modify res2 (1)
>
> {
> transaction nestedtx;
> //modify res1
> nestedtx.commit(); // (2)
> }
>
> rootrx.commit();
>
> like we´ve said, res2 isn´t taking part in the nested transaction,
> there is nothing between lines (1) and (2) that could create a
> conflict in res2.
>
> so if Boost.STM tries to discover conflicts as early as possible, why
> wasn´t the conflict discovered in line (1)?
>

Because other transaction on another thread has committed an update on res2
between (1) and (2). Depending on the Validation policy the STM system will
either invalidate every transaction that can not succeed (setting its stae
to rollback only), or do nothing. When validation is used , the victim
transaction will see that it is a victim when try to use this resource res2
and then abort itself.

Stefan Strasser-2 wrote:
>
>
> is Boost.STM checking for conflicts regularily, but not on every
> access, so line (1) doesn´t check for conflicts but you want to check
> for conflicts if the nestedtx takes, like, 10 seconds of runtime?
>

STM check for conflicts in any access. So it is able to see a conflict in
(1).

Stefan Strasser-2 wrote:
>
>
> if that´s the case we could implement something in
> basic_transaction_manager that regularily calls a resource manager so
> it can check for conflicts e.g. once every second even if a resource
> doesn´t take part in a transaction.
>

I don't think polling will be satisfactory

Stefan Strasser-2 wrote:
>
> what exactly triggers that in Boost.STM at the moment?
>

STM check also for rollback only state in any access or nested transaction
creation. This rollback only state can be set by other transaction as
explained above.

Stefan Strasser-2 wrote:
>
>
> I understand that this must be part of regular calls by the user and
> cannot be part of another thread, because the exception must be thrown
> in the user´s thread. but I don´t think that is a reason to drop the
> lazy construction of resource transactions entirely.
>
> take e.g. using Boost.STM and using a remote SQL database together,
> both managed by Boost.Transaction.
> starting a transaction to access boost.STM would automatically send a
> BEGIN to a, possibly remote, SQL database, if resource transaction
> aren´t lazily constructed, even though all you wanted to do is access
> some transactional memory.
>
>
I understand the intent of lazy constructing the local transactions. IMO
this lazy construction can be done, but as soon as a resource has already a
transaction, any global nested transaction should create a local transaction
on it. All the resources have the same nested level of transaction except
those that have none.
This should solve the preceding issue, and let STM check for rollback only
as soon as possible.

Stefan Strasser-2 wrote:
>
>>> I don't understand what difference that makes. I thought your point was
>>> that
>>> the transaction manager should be stored as an invariant singleton.
>>> How is that possible, with or without mixin? What does the mixim
>>> accomplish?
>>> What is the difference between instance() and the current active()?
>>
>> The trick is that instance is implemented by the Final class, and so
>> can call a specific construtor.
>> Your active() function is implemented by basic_transaction_manager,
>> which is not able to make differences.
>> basic_transaction_manager instance function could in addition ensure
>> that there is a single instance, but doesn't build it.
>
> I think I know what you mean now, but are you really sure you prefer
> that approach? I see several problems with it, IIUC.
>
> example:
>
> typedef basic_transaction_manager<my_mixin,...> txmgr;
>
> struct my_mixin{
> txmgr &instance(){
> //construct transaction manager and accompanying resources,
> //using this->db_filename;
> }
> static char *db_filename;
> ...
> };
>
>
> int main(){
> my_mixin::db_filename="file.db";
> my_mixin::...=...;
> ...
> basic_transaction<txmgr> tx;
> ...
> tx.commit();
> }
>
> 1. it´s strange code in my book. requiring the user to initialize
> runtime configuration options before it is lazily constructed by a
> call to instance() of basic_transaction.
> 2. the fact that it is lazily constructed requires the call to
> instance() be protected by a mutex, or call_once. this is a global
> mutex, spanning all threads, locked at each call to
> basic_transaction_manager::active().
>
> did I get that right? if this is not what you meant please provide a
> code example.
>
>
It is extrange also tome. Well, I don' use the mixin idiom tis way. For the
mutex a double locking patter solve the issue of locking at each call to
active(). I will do as follows:

struct txmgr : basic_transaction_manager<txmgr,...> {
   txmgr &instance(){
     static txmgr* instance_;
     static mutex mtx_;
     if (instance_==0) {
        scoped_lock<mutex> lk(mtx_);
        if (instance_==0) instance_ = new txmgr(...);
     } // here instance_!= 0
     return *instance_;
   }
   static char *db_filename;
   ...
};
char * txmgr::db_filename="file.db";

int main(){
   basic_transaction<txmgr> tx;
   ...
   tx.commit();
}

Can you found this code on your book? ;-)

Best,
Vicente

-- 
View this message in context: http://old.nabble.com/-transaction--New-Boost.Transaction-library-under-discussion-tp27210255p27266047.html
Sent from the Boost - Dev mailing list archive at Nabble.com.

Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk