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

Reply via email to