2 Replies Latest reply on Aug 24, 2009 11:33 PM by philippecote

    UserTransaction in Asynchronous Method (POJO)

    philippecote

      Hi,


      I'm trying to do some batch processing of thousands of records and would like to commit my transaction every 20 records so as to speed up things (very large transactions slow down as they go). Right now, the work is performed in a method with the @Asynchronous annotation and it seems I cannot control the transaction.


      I've tried marking the method @Transactional(TransactionPropagationType.NEVER), but Seam creates a transaction anyway.


      I've also tried using Transaction.getInstance().commit(), but it doesn't seem to be the same transaction as the one that my components are using within that method.


      By the way, this method is called directly as a JSF/MyFaces page action, and I'm not using EJB.


      Is there any way I could force the transaction to be user-managed in that context ?


      Best,


      Philippe

        • 1. Re: UserTransaction in Asynchronous Method (POJO)
          jeanluc

          I'm trying to do some batch processing of thousands of records and would like to commit my transaction every 20 records so as to speed up things (very large transactions slow down as they go).

          Something to check: is it slow because of the transaction or because of the large persistence context? You can address the latter by flushing the PC periodically and using batching (check the Hibernate docs for details). This doesn't preclude your original question but should be an incremental improvement.




          I've also tried using Transaction.getInstance().commit(), but it doesn't seem to be the same transaction as the one that my components are using within that method

          I haven't used POJOs and @Transactional (just EJBs) but this strikes me as odd. If there is a transaction under way, it's associated with the thread so even without looking at the docs, I'd expect Transaction.getInstance() to return it. If I understand correctly, you have an @Asynchronous method on a POJO marked @Transactional and that method does the batch processing inside it. If Seam creates a transaction automatically when this method is invoked, then this is the transaction associated with the thread so it should be returned by Transaction.getInstance(). Now, are you sure a transaction is indeed created by Seam in this case? A debugger and some stepping through Seam's code should provide some insight.

          • 2. Re: UserTransaction in Asynchronous Method (POJO)
            philippecote

            Something to check: is it slow because of the transaction or because of the large persistence context? You can address the latter by flushing the PC periodically and using batching (check the Hibernate docs for details). This doesn't preclude your original question but should be an incremental improvement.

            I flush the PersistenceContext every 10 items, so it should be fast... The thing is, the first batch of 10 items is really fast, the second is fast, the third is noticeably slower, etc.. by the tenth batch, it is like 20 times slower... It's really strange.



            I haven't used POJOs and @Transactional (just EJBs) but this strikes me as odd. If there is a transaction under way, it's associated with the thread so even without looking at the docs, I'd expect Transaction.getInstance() to return it. If I understand correctly, you have an @Asynchronous method on a POJO marked @Transactional and that method does the batch processing inside it. If Seam creates a transaction automatically when this method is invoked, then this is the transaction associated with the thread so it should be returned by Transaction.getInstance(). Now, are you sure a transaction is indeed created by Seam in this case? A debugger and some stepping through Seam's code should provide some insight.

            I'll give that a try !


            Thanks,


            Philippe