Best practices: Persistence and Transaction
baradon May 29, 2012 4:19 PMHi 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