
On Tue, Jan 19, 2010 at 7:23 AM, Stefan Strasser <strasser@uni-bremen.de> wrote:
Am Tuesday 19 January 2010 05:39:30 schrieb Bob Walters:
On Mon, Jan 18, 2010 at 4:02 PM, Stefan Strasser <strasser@uni-bremen.de> 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.