> On Sep 25, 2015, at 11:43 AM, Andy Seaborne <[email protected]> wrote:
>
> It'll depend on the status of "end" -- I have considered the transaction to
> run from begin() to end() and end() in a W transaction without commit() or
> abort() is an error.
Ah, I failed to understand this correctly. I thought end() in a WRITE
transaction without commit() or abort() amounted to abort(). Your semantics are
clearer. My current semantics leaves a disconcerting overlap between abort()
and end(). But it does leave me confused about the exact intent of end() in a
WRITE transaction, because Transactional itself is documented: “The write
lifcycle is: begin(WRITE) ... abort() or commit() [end()is optional]” and if
end() is optional, what exactly does it mean in that context?
> c.f. R transaction of begin(R)-end() scoping.
> The idiom is then (and can be made nicer in Java8):
> begin(W)
> try {
> ... reads and writes ...
> } finally { end() ; }
>
> or variations with an auto-abort on exceptions. The try{} is a consistency
> scope. That does not work with the auto-autocommit.
But that is more or less what I am doing with the auto-transact (and mixed with
some Java 8 juice), just wrapped in a test to see whether the thread is already
inside a transaction first. I do think that mixing explicit and implicit
transactions could be very confusing.
> In your case begin(W)-end() is a silent abort?
Yes, and I now appreciate the problematic nature of that a little better.
> BTW what happens if you get end-end? index().end(); is called repeatedly.
> Does that matter? (haven't had time to look at that)
Not on my implementation, although because I let QuadTable inherit
Transactional, I did not write that into the definition of QuadTable::end. It’s
now clear to me that I didn’t understand Transactional::end well enough to
narrow its semantic correctly anyway.
> So in a multithreaded environment, the autocommit despite being inside the
> begin-end is not consistent with the begin-commit part. Needs thinking about.
In the 624 branch there is no auto-transact _inside_ a begin-end, or at least,
if there is, that’s a bug for me to fix, and I think that the tests in
TestDatasetGraphInMemoryThreading show that there is not. Once you have used
begin(), you do not get auto-transact in play until you are back out of that
transaction, one way or another. Then it reengages. Unless I misunderstand you?
> A general point : we need to decide the fine grain details of the transaction
> models (or variations) we want to provide. Until now it's been TDB and
> DatasetGraphWithLock so not a wide range of choices pushing the design
> boundaries and stuff is implicit. Great thing about 624 is sorting that out.
That makes me feel a little better about not hitting the contracts quite right.
{grin}
> Current TDB works non-transactionally until the first begin then explicit
> transaction only. That's to maximise compatibility. autocommit and disk is
> dire (disk I/O per quad add is going to easily become painful - just look at
> many database lists with "why does my simple app go so slow" questions)l in
> -memory is different.
Right, that’s why I felt pretty safe with the auto-transact thing. A new
transaction on the persistent map implementation is just setting a couple of
flags and taking off a couple of ThreadLocal references, very cheap. I would
think that it would be quite cheap for almost any in-memory implementation.
> TDB non-transactional isn't even an implicit transaction. Current TDB2 is
> explicit transaction only because (1) it has no concept of update in-place
> due to immutable data structures and (2) I haven't spent any time on it.
> I like the Java8 style Txn.executeWrite style (maybe shorted names - details).
I want to be sure that I’m using the words “explicit” and “implicit” the same
way you are. I mean by using them to distinguish between the client controlling
transaction boundaries (explicit) and Jena controlling them (implicit). Is that
what you mean?
> In TDB2, transaction are promotable (read to write) though it is allowed only
> if no W transaction has run (strictly, started) and started it's own version
> of the DB. The API is more general that TDB2 supports. begin() and
> auto-promote is possible but not IIRC done. promote is the only time system
> aborts can happen so it creates interesting app issues.
Hm. This makes me realize that in the 624 branch, I have not specified
promotion abilities or lack thereof nearly well enough. I think that 624 the
scheme you describe for TDB2 makes a lot of sense. I will begin work on
implementing it, unless there is some reason not to that I am missing.
> My inclination is to suggest that we encourage explicit transactions as the
> recommended style. (Rhetorically) Is it to much of app burden? Don't know.
> Thoughts?
Putting on my Jena user’s hat, I would think it’s doable, but it would put some
onus on Jena to a) document and publicize it really well (the way TDB works
really confused me as a user at first), and b) make it as easy as possible
(using idioms like those in Mantis Txn to which you referred above, maybe
adding other ancillary machinery with which more easily to assemble
transactions as explicit packages of operations… e.g. fluent builders or the
like). It could represent a barrier to adoption for some people if transactions
obtruded as a concern in really simple use cases.
---
A. Soroka
The University of Virginia Library