Naming aside, my favorite approach is to have an "executor" available from SessionFactory for accepting this functional-interface (lambda). The executor would be configured with whether to isolate the work and whether to transact it. Something like:
Executor getExecutor(boolean isolated, boolean transacted); And then, Executor defines: <T> T doInSession(Function<Session,T> work) so all-told: factory.getExecutor( true, true ).doInSession( session -> ... ) As Sanne says though we need a better name for Executor On Wed, Sep 14, 2016 at 3:17 PM Steve Ebersole <st...@hibernate.org> wrote: > Most transaction systems do not support nested transactions > > > On Wed, Sep 14, 2016 at 3:13 PM Sanne Grinovero <sa...@hibernate.org> > wrote: > >> On 14 September 2016 at 21:02, Steve Ebersole <st...@hibernate.org> >> wrote: >> > Also, why do you keep defining this in terms of Session, rather than >> > SessionFactory? >> >> I mentioned that same doubt in my first email of this thread. >> I think I prefer Session as that's what people interact with most of >> the time, and it's a better choice if we opt to make this a nested >> transaction of the current one; if it's meant to be totally >> independent yes then we should probably consider the SF. >> >> > >> > >> > On Wed, Sep 14, 2016 at 3:01 PM Steve Ebersole <st...@hibernate.org> >> wrote: >> >> >> >> "Better" according to whom? ;) >> >> >> >> I personally very much dislike the kind of API explosion this kind of >> >> thing leads to. >> >> >> >> >> >> On Wed, Sep 14, 2016 at 2:59 PM Sanne Grinovero <sa...@hibernate.org> >> >> wrote: >> >>> >> >>> On 14 September 2016 at 20:32, Steve Ebersole <st...@hibernate.org> >> >>> wrote: >> >>> > The problem with "execute in isolation" here is that the "isolation" >> >>> > aspect >> >>> > refers to being isolated from any current transaction. It says >> nothing >> >>> > about whether that stuff-to-execute should itself be transacted. >> This >> >>> > is >> >>> > why, for example, you see IsolationDelegate accept a `transacted` >> >>> > boolean >> >>> > argument. >> >>> > >> >>> > How would you propose we pass such a flag in this case? Or are you >> >>> > proposing that this always start a (new) transaction? >> >>> >> >>> I had only the (new) transaction case in mind, but sure you could add >> >>> a `transacted` boolean parameter. >> >>> >> >>> Or we make it explicit with a better method name: >> >>> >> >>> s.executeInSubtransaction( session -> session.save(...) ); >> >>> >> >>> Thanks, >> >>> Sanne >> >>> >> >>> >> >>> > >> >>> > On Wed, Sep 14, 2016 at 1:39 PM Sanne Grinovero < >> sa...@hibernate.org> >> >>> > wrote: >> >>> >> >> >>> >> Today porting some benchmark code to Hibernate ORM 5.2 I had >> several >> >>> >> difficulties around the fact that the code now needs to be >> different >> >>> >> depending on transactions being container managed or not. >> >>> >> >> >>> >> My goal was to have a single benchmark test which I could compile >> once >> >>> >> and run in either JavaSE or CMT; with some help from Steve I >> figured >> >>> >> the necessary incantations out but ... it looks very unpractical. >> >>> >> >> >>> >> One way is to use an isolation delegate, which looks like this: >> >>> >> >> >>> >> final SessionImplementor session = (SessionImplementor) s; >> >>> >> >> >>> >> >> >>> >> >> session.getTransactionCoordinator().createIsolationDelegate().delegateWork( >> >>> >> new WorkExecutorVisitable() { >> >>> >> @ Override >> >>> >> public Object accept(WorkExecutor executor, Connection >> >>> >> connection) throws SQLException { >> >>> >> /// Some work with PreparedStatement on Connection.. >> >>> >> } >> >>> >> }, true ); >> >>> >> >> >>> >> This worked fine for some raw SQL used for the benchmark >> >>> >> initialization, but in another case I'd prefer to use the Session >> API >> >>> >> rather than dealing with PreparedStatements and native connections; >> >>> >> it looks like we don't have an equivalent "run code in isolation" >> for >> >>> >> the Session ? >> >>> >> >> >>> >> It would be great if I could just pass a lambda to a Session and >> have >> >>> >> this executed on a "child Session" in the scope of a "child >> >>> >> Transaction", or just start and commit a transaction if there isn't >> >>> >> one. >> >>> >> >> >>> >> s.executeInIsolation( session -> session.save(...) ); >> >>> >> >> >>> >> So I'd expect that details like how to begin the transaction, how >> it >> >>> >> should be committed (or rolled back in case of exceptions), how to >> >>> >> lookup a TransactionManager, and especially how to not leak >> resources >> >>> >> should be handled for the user. >> >>> >> >> >>> >> Obviously the inner Session instance is a different one than the >> >>> >> outer, so any data returned by this block should be considered >> >>> >> detached; maybe this limitation would be clearer if the method was >> >>> >> hosted on SessionFactory or StatelessSession instead? >> >>> >> Although it wouldn't necessarily have the limitations of a >> >>> >> StalessSession, and it would be nice to have the inner transaction >> >>> >> behave as a nested one when there's already one in the host >> Session. >> >>> >> >> >>> >> Looking forward for comments and improvement ideas :) >> >>> >> >> >>> >> Thanks, >> >>> >> Sanne >> >>> >> _______________________________________________ >> >>> >> hibernate-dev mailing list >> >>> >> hibernate-dev@lists.jboss.org >> >>> >> https://lists.jboss.org/mailman/listinfo/hibernate-dev >> > _______________________________________________ hibernate-dev mailing list hibernate-dev@lists.jboss.org https://lists.jboss.org/mailman/listinfo/hibernate-dev