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(a)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(a)lists.jboss.org
https://lists.jboss.org/mailman/listinfo/hibernate-dev