Boost logo

Boost :

Subject: Re: [boost] [transaction] New Boost.Transaction library under discussion
From: Bob Walters (bob.s.walters_at_[hidden])
Date: 2010-01-19 13:53:51


On Tue, Jan 19, 2010 at 7:23 AM, Stefan Strasser <strasser_at_[hidden]> wrote:
> 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...)

OK. This would worry me if I was planning to use Boost.Persistent in an app.
I understand one aspect of the isolation in acid to imply that when a given
thread commits a transaction, all of the changes within that transaction
become visible to other threads at a single moment in time. Or put another way:

t1: modifies A and B, commits.
t2: reads A and sees the newly committed value from t1
t2: reads B it *must* see the committed value of B from t1, or from
some later commit, and not a value from before t1.

IIUC there is a race condtion which could allow t2 to see the older
value of B if t1 and t2 overlayed in just the right way. (?) Although
your optimistic locking will protect t2 from an update to an old
version of B, it won't prevent t2 from using B in a read-only manner
(IIUC?), thinking that the value is current and correct. To me
that's a problem.

I *think* my interpretation of the isolation requirement is correct
here. Or at least, I am pretty sure that all RDBMS provide this kind
of assurance. This is one of the main reasons that I ended up having
to lock the map during commit processing - to ensure the
moment-in-time application of all changes - I couldn't just update
entries sequentially.

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

I'm working on this currently with the checkpoint algorithm, and it
isn't checked in yet.
But I'm using a multimap keyed by chunk size to implement best fit.
One consequence of
this is that I'm not (currently) writing to the checkpoint
sequentially. It can seek around,
putting free space to use. I don't sync the file until all entries
for the checkpoint have
been written, so hopefully, that will help mitigate this.

> 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:
>
> <snip>

This looks very usable and even a bit familiar in the sense that I'm
also accumulating operations for later execution during commit.


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