4 Replies Latest reply on Jun 10, 2008 3:58 AM by dan.j.allen

    How Flexible are Seam Managed Transactions?

      Hi,


      I have an app that's almost ready to go live but during BETA testing we had to pull it because of transactional issues.


      Essentially most the app works well with Seam managed transactions except for one method which involves a file upload.


      Now the method that handles the file upload does the following:


      1. Receive the date stream and converts it to a .flv file


      2. Put in the database a reference to uploaded file and attach the reference to a user.


      Now the method works fine if upload times are short. Soon as we went to BETA with real uploads taking 5 mins or more I start getting hiberante DelayedPostInsertIdentifier exceptions. Now after reading the doc on this it says that Hibernate uses a place holder for an id insert when a persist call happens outside of a transaction. But hang on, I'm thinking 'Seam is managing the transactions right, so what happened to my transaction?'


      I can only guess the transaction silently timed out or something because the file upload has taken too long.


      If that is the case my question is how do I man handle the transactions in this isolated case and let Seam handle the other cases? Want I really want is to start a transaction and commit it around the db insert in this one method, I don't want a transaction around the whole request for this case,


      I'm using POJO's here not EJB's as well.


      Any help would be appreciated as we are going live on Monday if we can solve this issue. This is my first real LIVE important Seam app too so I really want to impress the client and potentially showcase it as well as I've learnt a lot on this project.


      Cheers


      Troy 

        • 1. Re: How Flexible are Seam Managed Transactions?
          dhinojosa

          Just wondering, are these file uploads occurring during a conversation?  If so, how long are your conversations?  I think the default is 2 minutes in components.xml. 


          Let us know.

          • 2. Re: How Flexible are Seam Managed Transactions?

            Hi Dan,



            The scope of the class is EVENT. However there is a conversation running as the candidate is injected into the UploadAction. Essentially the code looks like the following:



            @Name("upload")
            @Scope(ScopeType.EVENT)
            public class UploadAction {
            ...
            
              @In
              private Candidate candidate;
            
              public void upload() {
                // create the file reference
                VideoFileReference ref = new VideoFileReference();
                ...
                entityManager.persist(ref);
                candidate.getVideos().add(ref);
                entityManager.merge(candidate);
                ...
            
                // does the conversion here
              }
            
            }




            The persit line stores a DelayedPostInsertIdentifier and the exception happens on the merge line two lines later.


            Cheers


            Troy

            • 3. Re: How Flexible are Seam Managed Transactions?

              After experimenting with the jboss JTA settings and changing timeouts, this confirms what I thought.


              If I increase the timeout to 600 secs then we can upload bigger files (40mb). If I decrease it to 30 secs then all of a sudden we get the error with 1mb files.


              So I guess I really need a way to control that start of that transaction and have it start after the uploaded data has finished streaming to the server :)



              Cheers


              Troy

              • 4. Re: How Flexible are Seam Managed Transactions?
                dan.j.allen

                Great use case. Here's what you can do. While Seam manages transactions around the request, you still have full access to it as well. Create a PhaseListener and disable the transaction around the UPDATE_MODEL_VALUES phase. You do this by committing the transaction before the phase:


                Transaction.instance().commit()


                and starting it again after the phase


                Transaction.instance().begin()


                I once had to do this to get fine-grained control over transactions in an action method. Remember, Seam helps you, it doesn't force you. Do what you feel is necessary. Let us know how it works out.