I have to correct myself, you won't get nested transactions with @CommitAfter, because its implementation checks if another transaction is active -- it won't start another transaction:
https://github.com/apache/tapestry-5/blob/master/tapestry-jpa/src/main/java/org/apache/tapestry5/internal/jpa/CommitAfterMethodAdvice.java#L41-L44 public void advise(final MethodInvocation invocation) { final EntityTransaction transaction = getTransaction(); if (transaction != null && !transaction.isActive()) { transaction.begin(); } But advice will still be executed, and your transaction that started by interceptor of method b() will be committed by interceptor of method a() -- which may be not that behavior you expected, due to implementation details of @CommitAfter: https://github.com/apache/tapestry-5/blob/master/tapestry-jpa/src/main/java/org/apache/tapestry5/internal/jpa/CommitAfterMethodAdvice.java#L61-L64 if (transaction != null && transaction.isActive()) { transaction.commit(); } On Fri, Aug 23, 2013 at 11:52 AM, Dmitry Gusev <dmitry.gu...@gmail.com>wrote: > > > > On Fri, Aug 23, 2013 at 11:11 AM, Martin Kersten < > martin.kersten...@gmail.com> wrote: > >> I review some code and I ran into the transaction issue. Annotating a >> service @CommitAfter seams to be inappropriate if you have another service >> method using it and is itself annotated with the @CommitAfter. >> >> The problem I have seams within the documentation. For @CommitAfter the >> documentation states that the transaction is committed at the end of the >> method. >> >> Therefore I think that for the case: >> @CommitAfter >> a() {...} >> >> @CommitAfter >> b() { a(); } >> >> At least two commits will happen for each of those commits. Am I right >> here? >> >> > Not exactly. If both a() and b() are from the same interface -- then only > one transaction will be committed. > This is because tapestry wraps methods a() and b() with advices, but this > happens on the proxies, not on the implementation classes. > > So if you call your method b() via proxy -- then interceptor for b() will > start the transaction, then method b() will call method a() on the > implementation class -- in this case no interceptors will be involved, > hence you won't get another transaction. > > You're getting proxy references when you @Inject'ing your services. > > You can see this by examining stack trace if you put a breakpoint in > method a(). > > But if you put method a() to Intf1 and b() to Intf2 and if you @Inject > Intf1 to Intf2 -- you should get two nested transactions. > > But your database should support nested transactions. > > >> There is the PersitenceContext annotation and that somehow I can use it to >> control transactional behavior but In my oppinion this focus about using a >> second session for two different persistent contexts. Am I right on this >> one? >> >> So in the end it looks like programming or using some other sort of >> mechanism that is aware of nested logical transactions and ignores the >> commit inside an ongoing transaction. This behavior can be introduced >> using >> HibernateSessionManager. >> >> There is also this post >> >> http://tawus.wordpress.com/2011/04/23/tapestry-magic-5-advising-services/which >> describes exactly what I need. >> >> The question here is there anything shipped with tapestry that allows this >> kind of behavior or am I missunderstanding @CommitAfter and this behavior >> is already present? >> >> Is there a standard way to control whether there is a ReadOnly transaction >> going on or not? I didnt found anything about it. Maybe I am blind. :) >> >> >> Cheers and Thank you, >> >> Martin (Kersten), >> Germany >> > > > > -- > Dmitry Gusev > > AnjLab Team > http://anjlab.com > -- Dmitry Gusev AnjLab Team http://anjlab.com