Boost logo

Boost :

Subject: Re: [boost] [transaction] New Boost.Transactionlibraryunderdiscussion
From: strasser_at_[hidden]
Date: 2010-01-21 14:48:54

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)


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)?

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?

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.

what exactly triggers that in Boost.STM at the moment?

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 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.


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(){
   basic_transaction<txmgr> tx;

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

did I get that right? if this is not what you meant please provide a
code example.



Boost list run by bdawes at, gregod at, cpdaniel at, john at