Why doesn't Neo4j handle "the work" in success instead of "finish" ?
On Tue, Oct 11, 2011 at 12:15 PM, Rickard Öberg <[email protected]> wrote: > Hi, > > Now that I work for Neo Technology I've started looking more in detail into > the Neo4j API, and found something very interesting with regard to how > transaction completion is handled. > > The idea is to simplify exception handling. Example code: > Transaction tx = ...; > try > { > ... > tx.success(); > } finally > { > tx.finish(); > } > --- > At first the above looked a little bit funny to me, but I got it explained > that it relates to how you handle exceptions. In the above, if there is any > exception (Exception, RuntimeException, Error) then the finish() call will > do a rollback, since success() has not been called. This way you don't have > to do tx.rollback() in catch statements, since theoretically you would have > to catch Throwable to be sure you have covered all cases. I.e. this is > unsafe: > UnitOfWork uow = ...; > try > { > uow.complete(); > } catch (Exception ex) > { > uow.discard(); > } > --- > ... since it does not handle RuntimeException or Error. > > So how does this affect us? Not much it turns out, because I realized that > uow.discard() on a closed UoW is a no-op. In other words, the following > becomes best practice: > UnitOfWork uow = ...; > try > { > ... > uow.complete(); > } finally > { > uow.discard(); > } > --- > With this template you are sure that the UoW is always handled properly > after the block exits. > > So, is this the same as Neo4j? Turns out, no actually not. The difference is > that in Neo4j the work happens in finish(), and so if that method throws a > TransactionFailureException, then you need a new try/catch outside of it to > handle. In Qi4j, the complete() method does the work (and discard() never > throws an exception), and so any exceptions from complete() can be handled > in the catch blocks of that try block. > > This also works if you have multiple UnitOfWork's in one try-block: > UnitOfWork uow = uowf.newUnitOfWork(); > try > { > ... > uow.complete(); > uow = uowf.newUnitOfWork(); > ... > uow.complete(); > } finally > { > uow.discard(); > } > > Does this seem like a good strategy? Do you prefer the Qi4j variant or the > Neo4j variant? Any other pros and cons I've missed? > > /Rickard > > _______________________________________________ > qi4j-dev mailing list > [email protected] > http://lists.ops4j.org/mailman/listinfo/qi4j-dev > -- Niclas Hedhman, Software Developer http://www.qi4j.org - New Energy for Java I live here; http://tinyurl.com/3xugrbk I work here; http://tinyurl.com/24svnvk I relax here; http://tinyurl.com/2cgsug _______________________________________________ qi4j-dev mailing list [email protected] http://lists.ops4j.org/mailman/listinfo/qi4j-dev

