Subject: Re: [boost] [transaction] New Boost.Transaction library under discussion
From: Stefan Strasser (strasser_at_[hidden])
Date: 2010-01-19 07:23:35


Am Tuesday 19 January 2010 05:39:30 schrieb Bob Walters:
> On Mon, Jan 18, 2010 at 4:02 PM, Stefan Strasser <strasser_at_[hidden]>
wrote:
> > an exclusive lock to the entire resource could be used to upheld the
> > state of the prepare phase until commit, but there are other ways.
> > my implementation e.g. never blocks another transaction from reading an
> > object, even during commit, based on
> > http://en.wikipedia.org/wiki/Optimistic_concurrency_control and
> > http://en.wikipedia.org/wiki/Multiversion_concurrency_control
>
> How do you control atomicity with this design? i.e. If a transaction
> modifies A and B and you are using a lock-free approach to update the
> cached versions of these objects from their shadow copies, how do
> you ensure that any other threads which might be reading A and B (or B and
> A) see the two entries consistently?

that's part of the optimistic approach, a transaction is allowed to see an
inconsistent (inter-object) state, but it is guaranteed to fail with an
isolation_exception, at commit at the latest, if it did.
(there were also pessimistic transactions once, but they fell victim to some
refactoring...)

> I'm not against throwing away portions of my code base to better unify.

I'm neither.
could you point me to your free list/allocation code? my library spends a lot
of time allocating and deallocating disk space, I guess there could be
improvements.
my logger is already pretty generic (because I planned to use it for the
storage engine log and for the log of the transaction manager for distributed
transaction). here's some example code on how to use it:

typedef mpl::vector<
  map_inserted, //must be POD
  map_entry_removed,
  ...,
> entries;

olog<entries> myolog(...);

myolog << map_inserted(1,2,3);
myolog << map_entry_removed(4,5);

---
struct listener{
  void operator()(map_inserted){
  }
  void operator()(map_entry_removed){
  }
};
ilog<entries> myilog(...);
myilog >> listener();
hidden behind olog is all the log rolling and the syncing interval stuff we've 
discussed to ensure sequential writing performance.