-
1. Re: BypassInterceptors and RollbackInterceptor
gonzalad Dec 23, 2009 5:49 PM (in response to gonzalad)I think we're screwed here :
I've tried implementing rollback with @BypassInterceptors in :
- Servlet Filter : doesn't work since Seam has already committed the tx - see SeamPhaseListener.handleTransactionsAfterPhase().
- JSF PhaseListener : We don't have access to the generated exception. For instance, if we look at JSF 1.2 Sun RI exception handling in com.sun.faces.lifecycle.Phase.doPhase - we won't have access to ex local var :
try { if (!shouldSkip(context)) { execute(context); } } catch (Exception e) { if (LOGGER.isLoggable(Level.SEVERE)) { LOGGER.log(Level.SEVERE, "jsf.lifecycle.phase.exception", new Object[]{ this.getId().toString(), ((context.getViewRoot() != null) ? context.getViewRoot().getViewId() : ""), event}); } ex = e; } finally { handleAfterPhase(context, listeners, event);
So, we have the following options :
- use @BypassInterceptors, and handle tx rollback in your Seam component code
public void myMethod() { try { ... } catch (SomeException err) { Transaction.instance().setRollbackOnly(); throw err; } }
- or don't use @BypassInterceptors.
I hope I'm missing sthing, but for the moment, @BypassInterceptors cannot be used while this pb remains.
-
2. Re: BypassInterceptors and RollbackInterceptor
kapitanpetko Dec 24, 2009 3:33 AM (in response to gonzalad)Well, you disabled all of Seam interceptors, so you loose some of Seam's features. That is not really a problem, that's the way it works.
You can:
- Use EJB's, they handle rollback for you
- if you need POJO transaction support, use Spring
- write your own interceptor and apply only that
HTH
-
3. Re: BypassInterceptors and RollbackInterceptor
gonzalad Dec 29, 2009 4:54 PM (in response to gonzalad)Thanks,
I've made some more tests to know a bit about the Cpu cost of Seam interceptors.
A simple JSE calling a method on a Seam conversation Scoped components (my main class extends SeamTest).
The test calls the seam component method in a loop (100000 iterations), and I do 4 times this test.
Computer used : Pentium 4 CPU 3GHz
JVM : IBM JVM 1.5.0 SR6bNo tx management (transaction-management-enabled=
false
in components.xml - I was having trouble making it work with txManagement enabled).Test 1 - Interceptors activated - normal case Cost : 0.08 ms / call Test 2 - Action annotated with @BypassInterceptors Cost : 0,00056 ms / call Gain vs Test 1 : 143 Test 3 - Just declaring RollbackInterceptor in components.xml Cost : 0,01027 ms / call Gain vs Test 1 : 8 Test 4 - Interceptors activated, and I added a @In attribute in my seam component Cost : 0.14 ms / call Cost vs Test 1 : *2 Test 5 - like 4 but with 2 @In Cost : 0.17 ms / call So ~42000 par @In Test 6 - same as 1 but with Sun JRE 1.6.0_14-b08 Cost : 0.068 ms / call
-
4. Re: BypassInterceptors and RollbackInterceptor
gonzalad Dec 29, 2009 4:57 PM (in response to gonzalad)And finally, I've made some more tests on a seam demo app.
Those tests are unit test (1 user connected) so, they're not really accurate, but I don't have more time to do some load tests.
Time is measured with a custom filter.
I measure each page 8 times and discards the 2 worst results.
a. Interceptors activated - normal case 495 ms b. RollbackInterceptor declared in components.xml 406 ms Gain : 22% c. BypassInterceptor on all my actions. 398 ms Gain : 24% d. RollbackInterceptor declared in components.xml+ BypassInterceptor on all my actions 367 ms Gain : 35%
-
5. Re: BypassInterceptors and RollbackInterceptor
gonzalad Dec 29, 2009 5:02 PM (in response to gonzalad)Since we're using Spring with Seam, we'll :
- activate transaction demarcation on our spring services (Spring AoP)
- in components.xml : declare only RollbackInterceptor.
- annotate all our seam components with BypassInterceptor.
Sample components.xml fragment :
<core:init debug="@debug@"> <core:interceptors> <value>org.jboss.seam.transaction.RollbackInterceptor</value> </core:interceptors> </core:init>
Sample spring configuration :
<aop:config> <aop:pointcut id="businessServicePointcut" expression="execution(* *..service.*Manager.*(..))" /> <aop:advisor id="txAdvisor" advice-ref="txAdvice" pointcut-ref="businessServicePointcut"/> </aop:config> <tx:advice id="txAdvice"> <tx:attributes> <tx:method name="*" read-only="true" propagation="REQUIRED"/> </tx:attributes> </tx:advice>
Sample Seam component :
@Name("rechercherChargeClienteleAction") @Scope(ScopeType.CONVERSATION) @BypassInterceptors @SuppressWarnings("serial") public class RechercherChargeClienteleAction extends NumberedPagedListAction<ChargeClientele> { private String nom; private String user; @Override protected PageData<ChargeClientele> loadPage(int aFirstResult, int aResultCount) { ListeResultat<ChargeClientele> lListe = getChargeClienteleManager().findByNameAndUser(getNom(), getUser(), aFirstResult, aResultCount); return getPageData(lListe.getListe(), lListe.getNbTotalEnregistrements()); } public String getNom() { return nom; } public void setUser(String aUser) { user = aUser; } public String getUser() { return user; } public void setNom(String aNom) { nom = aNom; } public int getPageSize() { return evaluateValueExpression("#{pageSettings.pageSize}", Integer.class); } private IChargeClienteleManager getChargeClienteleManager() { return evaluateValueExpression("#{chargeClienteleManager}", IChargeClienteleManager.class); } }
-
6. Re: BypassInterceptors and RollbackInterceptor
kapitanpetko Dec 30, 2009 4:36 AM (in response to gonzalad)
Gonzalez Adrian wrote on Dec 29, 2009 17:02:
Since we're using Spring with Seam, we'll :- activate transaction demarcation on our spring services (Spring AoP)
- in components.xml : declare only RollbackInterceptor.
- annotate all our seam components with BypassInterceptor.
Do you really need the RollbackInterceptor? Doesn't Spring AOP handle rollback for you? AFAIK, the AOP proxy Spring creates should rollback the transaction if any RuntimeException is thrown. I have never used Spring with Seam, but I don't see why it shouldn't work.
-
7. Re: BypassInterceptors and RollbackInterceptor
gonzalad Dec 30, 2009 12:13 PM (in response to gonzalad)
Do you really need the RollbackInterceptor? Doesn't Spring AOP handle rollback for you?Yes Spring Aop handles rollback for my services (and so, I don't need RollbackInterceptor for my actions since they call a service).
In fact since I annotate all my seam components with @BypassInterceptors, no interceptor is applied on my components (seam doesn't even create a dynamic proxy !).
RollbackInterceptor is only used for seam native components (ie. theme, entityManager, ...) in order to optimize the call for those kind of components.
I think I could remove the RollbackInterceptor interceptor for seam native components, but I didn't tested it enough and fear any possible side effects.
-
8. Re: BypassInterceptors and RollbackInterceptor
kapitanpetko Jan 4, 2010 2:25 AM (in response to gonzalad)
Gonzalez Adrian wrote on Dec 30, 2009 12:13:
In fact since I annotate all my seam components with @BypassInterceptors, no interceptor is applied on my components (seam doesn't even create a dynamic proxy !).
RollbackInterceptor is only used for seam native components (ie. theme, entityManager, ...) in order to optimize the call for those kind of components.If that is the case, you are probably better off leaving the Seam interceptor chain as is. It will not be applied to your action classes anyway. You are aware that transactions are not the only thing handled with interceptors, right? Things like conversation management with @Begin/@End, ascynchronous methods, SFSB removal, events and security are also implemented with interceptors. If you are using neither of those, you are probably OK, but just a heads up.
-
9. Re: BypassInterceptors and RollbackInterceptor
gonzalad Jan 5, 2010 10:24 AM (in response to gonzalad)Thanks very much for you input Nikolay.
If that is the case, you are probably better off leaving the Seam interceptor chain as is. It will not be applied to your action classes anyway.I've removed the Seam inteceptor chain in the components.xml (only leaving RollbackInterceptor), and it works for my demo application (196 xhtml page - so a relatively big demo app).
I would like to test it in a real application (checking performance benefits on adding / removing seam interceptor chain for seam native components), but I'm going out of time - pity.
Anyway, if one day I have problems I'll remember to add the interceptors back in components.xml ;)
You are aware that transactions are not the only thing handled with interceptors, right?Yes, checked last week every interceptor to make sure I didn't used them (and more importantly that Seam doesn't rely on them).
To do it, I've just looked at the isInterceptorEnabled() method of each interceptor.Here are my quick notes, if it can help someone, but you should better look at Seam interceptors code directly :
- org.jboss.seam.core.SynchronizationInterceptor : added on Session and Page components or components using @Synchronize.
- org.jboss.seam.async.AsynchronousInterceptor : added on components using @Asynchronous.
- org.jboss.seam.ejb.RemoveInterceptor : added on statefull ejb components.
- org.jboss.seam.persistence.HibernateSessionProxyInterceptor : added on statefull or stateless ejb components.
- org.jboss.seam.persistence.EntityManagerProxyInterceptor : added on statefull or stateless ejb components.
- org.jboss.seam.core.MethodContextInterceptor : usefull if you need access to Contexts.getMethodContext().
- org.jboss.seam.core.EventInterceptor : added on components using @RaiseEvent.
- org.jboss.seam.core.ConversationalInterceptor : added on components using @Conversational.
- org.jboss.seam.bpm.BusinessProcessInterceptor : added if jBPM jars are on your CLASSPATH. Usefulle if you use @StartTask, @EndTask, @Transition, @ResumeProcess annotations.
- org.jboss.seam.core.ConversationInterceptor : added if you use @Begin, @End, @StartTask, @BeginTask, @EndTask annotations.
- org.jboss.seam.core.BijectionInterceptor : added if you use @In, Out, @DataModelSelection, @RequestParameter, @DataModel annotations.
- org.jboss.seam.transaction.RollbackInterceptor : always activated marks current transaction to rollback when your seam components generated an unchecked exception (or exception annotated with @ApplicationException) : usefull for Seam javabean components.
- org.jboss.seam.transaction.TransactionInterceptor : added if the component is a javabean and if you use @Transactional.
- org.jboss.seam.webservice.WSSecurityInterceptor : if seam component annotated with @WebService and @Restrict.
- org.jboss.seam.security.SecurityInterceptor : if seam component annotated with @Restrict (and without @WebService).
All in all, Seam interception management is efficient so that if seam detected at startup that an interceptor isn't needed for a component, it doesn't register it for this interceptor list, and the interceptor is never executed.