1 2 Previous Next 19 Replies Latest reply on Jun 17, 2007 6:54 AM by Edwin van der Elst

    Transaction Demarcation

    Toni Beckman Novice

      Hi,

      I have a webapplication, which imports data about customers from a text file. Each row contains a record out of which several entity bean are being created and assembled.

      The function, which reads in a line an creates those entity beans and sets up the relationships between them is called "createCustomer(String line)". This method gets called several times from another function called "createCustomers()".

      I have noticed that the whole process is treated as a unit of work. Either all customers and relating entity beans are created or none. They seem to span one single transaction.

      Assuming that the client call to "createCustomers()" is triggered through a seam web request by the user, how would I assure that for each call to "createCustomer(String line)" a new transaction is spanned?

      I want to narrow the transaction scope down to a single customer instead of all the customers.

      How would I use the @Transactional attribute to achieve that? From reading the oreilly book I figured I would have to use the transaction attribute "Requires New", which however does not seem to exist as an attribute in seam.

        • 1. Re: Transaction Demarcation
          Dave Whittaker Novice

          Check out @TransactionAttribute in the EJB3 spec.

          http://trailblazer.demo.jboss.com/EJB3Trail/services/transaction/

          If you're not using EJB3 Hibernate might have it's own transaction annotations but I'm not aware of them.

          • 2. Re: Transaction Demarcation
            Denis Karpov Newbie

            What do you need is user transactions.

            import javax.ejb.TransactionManagement;
            import javax.ejb.TransactionManagementType;
            ....
            
            @TransactionManagement(TransactionManagementType.BEAN)
            public class Qqqqq.......
             @In
             private EntityManager entityManager;
             @Resource
             public UserTransaction utx;
            
            ......
             utx.begin();
             utx.commit();
             utx.rollback();
            ......
            }
            


            • 3. Re: Transaction Demarcation
              Toni Beckman Novice

              Well, I don't think I can use the EJB3 notations in seam. I tried and it does not work or have any effect.

              Trying to acces a user transaction I got:

              java.lang.IllegalStateException: Container MessageManager: it is illegal to inject UserTransaction

              So this does not seem to be an option either.

              Does anybody know how I could start several transactions and commit each during the time of a user web request?

              Also if the user clicks somehwere else, so that no response is generated the initial task should complete.

              • 4. Re: Transaction Demarcation
                Toni Beckman Novice

                Hi,

                I'm still trying to figure out how to span several transactions within the scope of one web request/response.

                I guess using a TransactionalSeamPhaseListener is not an option, because it always starts a transaction at the beginning and end of the request ie response respectively.

                So I guess I have to use a SeamPhaseListener and then start the transactions by myself?! But I think using the SeamPhaseListener will give me LIEs.

                Is it possible in Seam at all to span several transactions within one http request/response cyle???

                • 5. Re: Transaction Demarcation
                  Christian Bauer Master

                  Transaction != Persistence Context

                  As long as there is a persistence context, you can lazy load stuff.

                  Just use the UserTransaction API or EJB3 transaction annotations to set transaction boundaries.

                  The RENDER RESPONSE phase, and any data access not in the INVOKE APPLICATION PHASE (where your custom transaction assembly would most likely apply) is then executing effectively in auto-commit mode.

                  • 6. Re: Transaction Demarcation
                    Christian Bauer Master

                    By the way, you can always use the TransactionalSeamPhaseListener and @TransactionAttribute(REQUIRES_NEW) to suspend the existing transaction during a particular method call in INVOKE APPLICATION. Your method then executes in a new transaction context - which is committed when the method returns.

                    As long as your are using a Seam-managed persistence context with@In EntityManager, this should work fine even if your method calls other transactional methods that use the entity manager. I wouldn't try this with @PersistenceContext, the rules for propagation are complicated because they are tightly bound to the transaction propagation.

                    • 7. Re: Transaction Demarcation
                      Toni Beckman Novice

                       

                      "christian.bauer@jboss.com" wrote:
                      By the way, you can always use the TransactionalSeamPhaseListener and @TransactionAttribute(REQUIRES_NEW) to suspend the existing transaction during a particular method call in INVOKE APPLICATION. Your method then executes in a new transaction context - which is committed when the method returns.


                      Have you actually tried that? I'm asking because it definitely does not work with my application (Seam 1.1, JBoss 4.0.5).

                      I also recall that somehwere Gavin notes that in particular this type of transaction attribute is not supported by the @Transactional notation, which I guess you would have to use in Seam instead of @TransactionAttribute?!

                      http://docs.jboss.com/seam/1.1.1.GA/api/org/jboss/seam/annotations/TransactionPropagationType.html

                      • 8. Re: Transaction Demarcation
                        Christian Bauer Master

                        @Transactional is a hint for JavaBeans! It is not used if you have EJB 3.0 components.

                        • 9. Re: Transaction Demarcation
                          Toni Beckman Novice

                          So you are saying that "@Transactional" should only be used on Seam components, which are missing the tags @Stateless or @Stateful?

                          And that seam components which are tagged with @Stateless or @Stateful should refer/use "@TransactionAttribute" instead ?

                          • 11. Re: Transaction Demarcation
                            Toni Beckman Novice

                            Well thank you for clarifying this! I was already wondering why seam would introduce an extra transaction annotation, which lacks some of the EJB3 transactional attributes.


                            By the way, you can always use the TransactionalSeamPhaseListener and @TransactionAttribute(REQUIRES_NEW) to suspend the existing transaction during a particular method call in INVOKE APPLICATION. Your method then executes in a new transaction context - which is committed when the method returns.

                            As long as your are using a Seam-managed persistence context with@In EntityManager, this should work fine even if your method calls other transactional methods that use the entity manager.


                            However, I still have to say that tagging my method with @TransactionAttribute(REQUIRES_NEW) and using a "TransactionalSeamPhaseListener" does not work: All the data is written at the very end of the invocation, which takes about 20 minutes.

                            Do you have any idea why your suggestion does/might not work in my szenario, which is:

                            User klicks a link, which calls an action method of a SFSB (statefull), which then calls a SLSB (stateless), which start inserting many entities by repeately calling local methods of which some again call another SLSB's method.


                            BTW: In another forum thread somebody told me to use @TransactionTimeout, when I ran into a TransactionTimeout exception, which occurred because the process lasts for 20 minutes. I tried that without any luck.

                            I had to increase the Timeout in jta-service.xml in order for this single transaction to complete at all. Because the suggested annotation did not extend the Timeout and because your suggestions does not work for me either, I get the feeling that those EJB3 annotations are not working with/on seam components.

                            • 12. Re: Transaction Demarcation
                              Christian Bauer Master

                              You need to enable logging for the transaction service in your server and watch when transactions are created and when they are committed.

                              • 13. Re: Transaction Demarcation
                                Toni Beckman Novice

                                How and where ca I turn this on?

                                I noticed something very interesing so: I used "@TransactionAttribute(TransactionAttributeType.NEVER)"
                                on the first call to the SLSB (stateless) and the transaction gets stopped! In the logfile I see:

                                007-05-04 14:56:08,090 ERROR [org.jboss.ejb.txtimer.TimerImpl] Error invoking ejbTimeout: javax.ejb.EJBException: java.lang.IllegalStateException: Transaction present on server in Never call

                                However, if I place the annotation on the method, which actually creates a single entity and gets called by, then nothing happens. So this explains why placing @TransactionAttribute(REQUIRES_NEW) on it does not work either!

                                The big question now is why? Do you have idea? Here once more the flow of execution:

                                1. User clicks button
                                2. userSchedule() gets called on SFSB1
                                3. scheduleMessages() gets called on SLSB1 by SFSB1
                                4. scheduleMessage() gets called by SLSB1 many times

                                Placing "@TransactionAttribute(TransactionAttributeType.NEVER)" on scheduleMessages() stops the flow of execution. However, placing it on scheduleMessage() has no effect!!

                                Why is that?

                                • 14. Re: Transaction Demarcation
                                  Christian Bauer Master

                                   

                                  3. scheduleMessages() gets called on SLSB1 by SFSB1


                                  Maybe because it's a re-entrant call? I don't know, ask on the EJB3 forum.


                                  1 2 Previous Next