
----- Original Message ----- From: "Stefan Strasser" <strasser@uni-bremen.de> To: <boost@lists.boost.org> Sent: Monday, January 18, 2010 1:21 AM Subject: Re: [boost] Boost library submission (poll for interest)
Am Monday 18 January 2010 00:25:54 schrieb vicente.botet:
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
I do, it's a virtual call for each access to a persistent object. note that if only a base class of the transaction manager is known to the "transactional entity" it can also only return a base class of the resource manager, so it also severly limits the interface of the resource managers, since there are no virtual template functions. but since we agree on the result there is no need to discuss this in detail I guess.
what do you think about the basic_* and alias approach? is that feasible for your library?
Yes I think so.
4. please have a look at the following parts of the documentation:
https://svn.boost.org/svn/boost/sandbox/persistent/libs/persistent/doc/ht ml/persistent/configuring.html#persistent.configuring.defaultconf
TransactionManager concept: https://svn.boost.org/svn/boost/sandbox/persistent/libs/persistent/doc/ht ml/boost/persistent/TransactionManager.html
ResourceManager concept: https://svn.boost.org/svn/boost/sandbox/persistent/libs/persistent/doc/ht ml/boost/persistent/ResourceManager.html
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.
right, the interface for distributed transactions is missing. there has to be at least a prepare_transaction(), a recover() and a transaction_id with a way to obtain it from a transaction object, so the transaction manager can log the IDs of the resource transactions in its distributed transaction log.
I also need a finish_transaction() but this is a minor issue. I'm quite sure this can be an empty function for your libraries.
Yes, this is the kind of functions I was looking for.
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?
I don't think it's documented except for the Reference. TransactionManager::transaction is sometimes called the "global transaction", and ResourceManager::transaction the "local transaction" in other systems.
I see, so TransactionManager::transaction is the distributed transaction, and ResourceManager::transaction can be persistent::transaction, stm::transaction, ...
the details are as follows:
the user creating a transaction scope:
transaction tx;
calls TransactionManager::begin_transaction and stores a TransactionManager::transaction. note that no resource manager is called at this point.
Does TransactionManager::begin_transaction makes a transaction or registers the stack allocated one? unspecified TM::begin_transaction() ; what about void TM::begin_transaction(TM::transaction&) ;
accessing a resource, e.g. by calling Locator::operator*, obtains ResourceManager::transaction by calling TransactionManager::resource_transaction(), and uses it to access the object. TransactionManager::resource_transaction() returns the ResourceManager::transaction that is associated with the TransactionManager::transaction. if there is none associated yet, ResourceManager::begin_transaction is called to create one.
OK. I understand the logic.
the point of all this is that if there are multiple resources used by a transaction manager, a local transactions in a resource manager is only started if the resource is actually used in this global transaction. for example most of my transactions may access Boost.STM transactional memory only, and only from time to time I access Boost.STM and Boost.Persistent in the same transaction.
if more than one ResourceManager::transaction's were created in the course of a global transaction, a two-phase-commit has to be performed.
Oh I see here the advantage to creating lazyly the ResourceManager::transaction that are needed.
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?
yes, one at a time. this might be rarely used, but it is possible to have 2 transaction managers of the same type if the right one is active at the time you access e.g. objects that use it. my (minor) point of this was that transactions are bound to threads, and transaction managers are bound to applications.
I agree with the last point :) I would like to see something in the line of namespace this_transaction { transaction* current(); ... } or namespace current_transaction { ... } Best, Vicente