4 Replies Latest reply on Mar 23, 2011 3:30 PM by marcio.dantas

    Concurrency problem with entityManager.flush()?

    thiagosil

      The problem i have is that if more then one user tries to execute the method below,
      apparently it locks the table on the database and it stays locked, and the application becomes more and more slow. The dateQuantity variable is usually not the same for two different users, so it doesnt look like its locking the same row.
      It only happens in production.


      I'm using Seam 2.1.2 and  hibernate3.2.6.ga.
      The class and the method with the problem is this:
      The event is thrown by a controller, that passes the entityManager.
      Any idea why this could be happening?


      @Scope(ScopeType.APPLICATION)
      public class DataCollectorManager
      {
           @Observer(CollectorConstants.ACCESS)
           public void collectAccess(EntityManager em)
           {
                ...
                
                em.merge(dateQuantity);
                em.flush();
           }     
      }



      Thanks in advance.

        • 1. Re: Concurrency problem with entityManager.flush()?
          marcio.dantas

          Who's managing you're transactions?
          The table or rows getting locked means that the transactions are not commiting.


          Maybe you're having deadlocks issues..
          What's your database? MS-SQL-Server 2000?

          • 2. Re: Concurrency problem with entityManager.flush()?
            thiagosil

            We are not explicitly managing the transactions, so i guess Seam is doing it.
            The database is oracle 10g. I'm trying to figure out why the transactions are not committing,
            but i have no clue.


            • 3. Re: Concurrency problem with entityManager.flush()?
              lvdberg

              Hi,


              You should try it in another scope and inject the entityManager the normal way. Try something like this:





              @Name("collectorObserver"
              public class DataCollectorManager
              {
              
              @In EntityManager em;
              
                   @Observer(CollectorConstants.ACCESS, create= true)
                      @Transactional
                   public void collectAccess(YourObjectYouWantSaved o)
                   {
                        
                        em.merge(o);
                        em.flush();
                   }     
              }



              You just raise an event with the right parameter and that's all there is.



              Leo

              • 4. Re: Concurrency problem with entityManager.flush()?
                marcio.dantas

                Seam uses some default transactions during request life cycle, but i think you should not be counting on them.
                Use Seam's annotated transactions like on the code above.



                In fact, maybe you should do a test turning off Seam's DFAULT transaction management.
                You're able to do it without hurting the annotated transactions.