1 Reply Latest reply on May 30, 2012 10:57 PM by Stephen Coy

    Best practices: Persistence and Transaction

    Heiner Lamprecht Newbie

      Hi all,

       

      suppose you have the following architecture (running on JBoss AS 5.1):

       

      Session Bean A is called by a timer frequently, requests data from an external web service, and passes this data on to Session Bean B on the same server (local interface).  This bean B receives the list of data items and stores them in a database.  Now, sometimes it may happen, that a single data item can not be stored into the database.  It doesn't matter and can be skipped, but it is essential for the system to keep on running and processing the rest of the items.

       

      public class BeanAImpl implements BeanA {
           @EJB
           private BeanB bb;
      
           @Timeout
           public void requestData(Timer t) {
                List<DataItem> dataList;
                // requests data, stores them in dataList ...
                bb.doStuff(dataList);
           }
      }
      
      public class BeanBImpl implements BeanB {
           @PersistenceUnit(unitName = "CommonsPU")
           private EntityManagerFactory emf;
      
           @Override
           public void doStuff(List<DataItem> dataList) {
                EntityManager em = emf.emf.createEntityManager();
      
                try {
                     for (DataItem item : dataList) {
                          em.persist(item);
                     }
                     em.flush();
                     em.close();
                } catch (PersistenceException ex) {
                     // Print log message
                }
           }
      }
      

       

      At the moment, we receive an exception from the database.  And afterwards the rest of the list can not be handled, as the transaction is no longer in progress.

       

      I'm looking for a good and clean solution and would like to get some opinions.  Of cause, in "user-centric" applications, one would present this error to the user and ask him what to do.  But in this case, there is no user to intervent.  The system needs to be robust to handle any/many kind of errors.

       

      Would it be better to use bean-managed-transaction here, creating a new transaction for every single item in the list?  Or would it be possible (and useful) to iterate through the list in bean A, change the doStuff() method to only accept a single item and annotate this method with a TransactionAttribute "REQUIRES_NEW"?

       

      Any idea and opinion appreciated.

       

       

      Cheers,

       

      Heiner

        • 1. Re: Best practices: Persistence and Transaction
          Stephen Coy Master

          You're on the right track with:

           

          change the doStuff() method to only accept a single item and annotate this method with a TransactionAttribute "REQUIRES_NEW"

           

          Remember that a transaction is a unit of work that either completely succeeds, or completely fails. Interaction with the database is part of that scenario.

           

          The other issue you will need to deal with is the size of your dataList. If it is too large then your encompassing transaction on the @Timeout method will timeout and cause other problems.

           

          I would consider sending batches of a 100 or so to a JMS queue and processing them in a message driven bean which calls doStuff() for each DataItem in a @RequiresNew transaction.