Boost logo

Boost :

Subject: Re: [boost] Boost library submission (poll for interest)
From: vicente.botet (vicente.botet_at_[hidden])
Date: 2010-01-17 18:25:54

----- Original Message -----
From: <strasser_at_[hidden]>
To: <boost_at_[hidden]>
Sent: Sunday, January 17, 2010 10:30 PM
Subject: Re: [boost] Boost library submission (poll for interest)

> Zitat von "vicente.botet" <vicente.botet_at_[hidden]>:
>>> Yes. Stefan had suggested this in private e-mails earlier, and I'll
>>> have to adapt to fit his interfaces.
>>> As I've alluded previously, I would like to see it possible to
>>> use Boost.Persistence with my library, as several shortcomings of
>>> STLdb would be addressed in that way. Part of doing that involved
>>> bringing all transaction control under one manager. Stefans library
>>> is the most robust in this sense, so I plan to work with and adapt to
>>> his interfaces.
>> I have proposed in a private mail to split its library in two
>> Boost.Transaction and Boost.Persistency. I think this is the right
>> direction.
> before I do that, I would like to have a thorough discussion of the
> design decisions I made, especially the first one of the list, because
> it deeply affects the way your libraries would have to be set up.
> 1.
> every transactional entity like a trans_map or a shared_loc must be
> aware of the static type of the transaction manager, which can change
> by user configuration.
> this results from the following:
> every access to a transactional entity without explicit "transaction"
> argument must go through the transaction manager
> ==> calls through transaction manager must be efficient
> ==> there can be no dynamic polymorphism
> ==> the static type of the transaction manager changes by
> configuration(a transaction manager using Boost.Persistent has another
> type than one that uses STLdb, which has another type than a
> transaction manager using both libraries)
> ==> all transactional entities must be aware of the static type of the
> transaction manager.
> so in my library every transactional entity is a template with the
> type of the transaction manager as parameter:
> basic_transaction<TxMgr>
> basic_shared_loc<T,TxMgr>
> basic_loc_multiset<T,TxMgr,...>
> and so on.
> for convenience of the user that only uses one type of transaction
> manager, there are aliases defined:
> transaction, alias for basic_transaction<transaction_manager>,
> shared_loc<T>, alias for basic_shared_loc<T,transaction_manager>
> ...
> transaction_manager is a typedef that currently is by default a
> transaction manager that uses Boost.Persistent, but can be changed by
> defining BOOST_PERSISTENT_CONFIGURATION before including the aliases.
> there are several obstacles with this approach:
> - every type that ought to be used with a configurable transaction
> manager must be a template.
> - C++98 has no template aliases.
> in C++0x shared_loc could be a simple alias of basic_shared_loc:
> template<class T>
> using shared_loc = basic_loc<T,transaction_manager>;
> in C++98 however a class "shared_loc" that acts like an alias for
> "basic_shared_loc" has to be implemented.
> this would have to be done for every class like that of your libraries, too.

I don't think the cost of dynamic polymorphism will be high respect to the cost of a transaction system, and even less if it concerns persistent objects. Anyway, I agree with the static approach. I think that once we will have static polymorphism, it would be very easy to add dynamic polymorphism.

> 2.
> do your libraries allow access by multiple threads to the SAME transaction?

Not yet, but I would like to explore how parallelism and transactions can work together.
> because this requires a mutex lock in the transaction manager for each
> access, which might be a performance concern?
> if your libraries only allow one thread to use a transaction, this
> mutex lock can be removed by changing a template argument of
> basic_transaction_manager.

what about having two classes, transaction and shared_transaction? The first one is local to a thread and could be used without the mutext, while the second can be shared between threads and need this mutex protection.

We can start by the non-shreable transaction.
> 3.
> transactions are bound to the current thread when they are created,
> but transaction managers are bound to the whole application.
> my_transaction_manager t1;
> my_transaction_manager t2;
> //t2 is the current transaction manager, even when another thread is
> started. bind() can be used to bind another transaction manager for
> all running threads.
> creating and binding of transaction managers is not thread-safe.

Sorry. I'm a little bit lost. Why do you need to change the instance of the transaction manager. I thought that there was only a transaction manager. When an application will need to change it?

> 4.
> please have a look at the following parts of the documentation:
> TransactionManager concept:
> ResourceManager concept:

I'm not sure if the interface of resource_manager is enough to implement a two-phase commit protocol, but we will see this once we talk about the protocol that ensure that the transaction is ACID for all the resources.

I see that there are TransactionManager::transaction and a ResourceManager::transaction types. Could you point on the documentation (if already written) how these types are correlated, and when these function are called?

struct TransactionManager {
  typedef unspecified transaction;
struct ResourceManager {
  typedef unspecified services; // A MPL Sequence of tags of all Service concepts implemented by this ResourceManager.
  typedef unspecified tag; // The tag that identifies this ResourceManager.
  typedef unspecified transaction;

  // public member functions
  unspecified begin_root_transaction() ;
  unspecified begin_nested_transaction(transaction &) ;
  void commit_transaction(transaction &) ;
  void rollback_transaction(transaction &) ;


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