2015-05-06 14:19 GMT+02:00 Emmanuel Bernard <emmanuel(a)hibernate.org>:
It’s an interesting idea.
Let me give you the reasons why I think the transaction API has merits.
There is already a notion of UnitOfWork that was named Conversation in
Seam / CDI. But its span is potentially longer than the span of the updates
window. The closer notion of a UnitOfWork is an EntityManager or a Session.
By introducing @UnitOfWork, you forgo all the integration between
application frameworks and transactions. Here you offer a solution
for CDI
but we would need one for Java EE non CDI and one for Spring and one for
Grails and one for…
The current integrations would continue to work. So e.g. EJB non-CDI would
still use JTA as is today. I don't find it to be a big problem there, as
it's much more under the covers (which is why it's nice to show EJBs in
demos ;). Same for the others basically.
I understand you reluctance to call a Tiger a Cat but they are commonly
referred as Cats.
Back to our problem, you either
- teach people that transaction is not what they might understand of
transactions - if they even know what that means these days ;)
- teach them a new concept that suspiciously looks like a transaction
anyways and force them to do the integration of that “thing” with their
universe.
I'd prefer the latter. The good thing is that it is up to us to
describe/document what the "thing" is, so we can manage expectations
towards it, far better then when using the term "transaction" which
automatically raises certain expectations (smart people will wonder how we
make it work, others may even fall into the trap and believe it is actually
TX).
I like the exploration of lamda usage for the Hibernate APIs but we
probably should think about it in the larger scheme of ORM and in this
async API trend. What could we do.
Note also that your example reflects a simple example where you *whole*
unit of work is very simple and does not span services / DAOs. If it spans
services / DAOs, then the lambda approach sort of fails a little by as you
need to reach the session from within these nested service calls.
Yes, that is a good point. Probably we'd also need something like
beginUnitOfWork(). Maybe something like this is the better approach:
session.buildUnitOfWork()
.onFailedGridDialectOperation( context -> {
// e.g. log failed op
return ErrorHandlingStrategy.ABORT;
} )
.onRollback( context -> {
// e.g. log applied ops
} )
.begin();
session.persist( order );
session.persist( customer );
session.finishUnitOfWork();
I am relatively open on these proposals but we need to flesh them out
much
better before we can consider them seriously (say for the next sprint).
Sure, it's not fully worked out, I just wanted to quickly gauge general
interest in this. I will file an issue.
> On 06 May 2015, at 11: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