[hibernate-dev] [OGM] Demarcating units of work

Sanne Grinovero sanne at hibernate.org
Wed May 6 05:13:38 EDT 2015

Did you consider that the existing definition of "Transaction
boundaries" can have different levels of isolation and guarantees,
depending on how the underlying components are configured?

I do agree with you that it's kind of weird that people write code
without making transactional requirements explicit in the code, but it
seems that the trend is to abstract from that and use the
"Transaction" term as a "Unit of work".

For example I find it strange that - in Java - one has to configure
the isolation levels of transactions to the safest (least efficient)
option possible among the types his *various* use cases require. It's
pretty obvious that it would be more efficient to choose those levels
as "profiles" based on use case, possibly bean or even method level.
I guess that's were complex applications split up in multiple deployments..

What is concerning is that the average developer will write Java code
making assumptions on the underlying transaction guarantees, and will
rarely communicate those as requirements to whoever configures it.
Is that what you aim to solve?

On 6 May 2015 at 10:01, Gunnar Morling <gunnar at hibernate.org> wrote:
> Hi,
> When talking to people about OGM, there is always that awkward moment when
> you need to explain that TX demarcation is required also for
> non-transactional data stores.
> While it makes sense for our purposes (we use the "TX cycle" to optimise
> the work sent to the backend etc.), I can understand people who find that
> odd API-wise. So I was thinking about how this could be improved.
> When it comes to CDI, a more "neutral" annotation (and a portable extension
> examining it) than @Transactional could be helpful:
>     @UnitOfWork
>     public void saveOrderAndCustomer(Order order, Customer customer) {
>         session.persist( order );
>         session.persist( customer );
>     }
> By means of the @UnitOfWork annotation it would be expressed that the
> entire method should run as one "transaction". This also could be used to
> specify an error handler for our new API to be applied for this unit of
> work:
>     @UnitOfWork(errorHandler=FailedOpsLoggingHandler.class)
>     public void saveOrderAndCustomer(Order order, Customer customer) { ... }
> In non-managed environments, Java-8-style Lambda expressions could be
> leveraged nicely to achieve the same:
>     session.runUnitOfWork( () -> {
>         session.persist( order );
>         session.persist( customer );
>     };
> This should feel much nicer to e.g. users of the MongoDB backend than
> invoking session.getTransaction().begin()/commit(). It also plays greatly
> together with the error handling stuff:
>     session.buildUnitOfWork( () -> {
>         session.persist( order );
>         session.persist( customer );
>     } )
>     .onFailedGridDialectOperation( context -> {
>         // e.g. log failed op
>         return ErrorHandlingStrategy.ABORT;
>     } )
>     .onRollback( context -> {
>         // e.g. log applied ops
>     } )
>     .run();
> Of course something equivalent could be done for Java 7, but it'd probably
> look not as concise.
> Any thoughts?
> Cheers,
> --Gunnar
> _______________________________________________
> hibernate-dev mailing list
> hibernate-dev at lists.jboss.org
> https://lists.jboss.org/mailman/listinfo/hibernate-dev

More information about the hibernate-dev mailing list