I tend to recommend to set any finder methods to SUPPORT which is far better in terms of performances and allow reusability of finder methods in business methods.
JLouis 2012/12/11 David Blevins <david.blev...@gmail.com> > Setting the LockModeType is good. Understand, though, that all the values > in LockModeType are not guaranteed to be supported in all databases. > > It doesn't address the core problem in that the transaction scope is > likely too broad. As a general rule *always* ensure your transactions are > as *small* as possible. In order to be very conscious about it it can help > to actually document the code and justify why two or more operations need > to be in the same transaction. It'll force you to think about transactions > more deliberately and ask yourself other questions like "where are my > transactions starting and stopping in the first place". > > In this particular situation, with default settings, you'll get one > transaction started for you when the @Schedule method fires. So > essentially, you're batch processing unrelated data in one transaction. If > Joe and Jane both send email with data, you're processing Jane's data in > Joe's transaction. As as well your email fetching time is getting included > in your transaction time. If your email server hangs, your transaction > hangs. > > So instead of: > > // TRANSACTION START > @Schedule(...) > public void processPendingEmail() { > > List<Email> emails = fetchEmail(); > for (Email email : emails) { > // parse email and insert records > } > } > // TRANSACTION END > > You want: > > @Schedule(...) > public void processPendingEmail() { > > List<Email> emails = fetchEmail(); > for (Email email : emails) { > // TRANSACTION START > // parse email and insert records > // TRANSACTION END > } > } > > This can be as easy as marking the `processPendingEmail` as > `@TransactionAttribute(NEVER)` then moving the insert logic to another EJB > method. Just make sure that if you move that logic to another method of > the same EJB that you don't invoke that method with a `this` reference or > you won't get container-managed transactions on that method call. (see this > reference for why): > > > http://stackoverflow.com/questions/3381002/how-is-the-return-value-of-sessioncontext-getbusinessobject-different-from-th/3384128#3384128 > > Hope this helps! > > > -David > > On Dec 11, 2012, at 12:21 PM, "Howard W. Smith, Jr." < > smithh032...@gmail.com> wrote: > > > Prior to adding this @Stateless EJB (that's invoked via @Schedule every > 10 > > minutes), my JSF web app has been running 100% okay without any deadlocks > > or anything else like that. > > > > So, is it okay if I just add optimistic locking, em.lock(entity, > > LockType.Optimistic) before any/all em.persist(...) that I have in the > > @Stateless EJB? > > > > JSF web app is working okay, because the JSF components call multiple > > @Stateless EJB that usually do any of the following, SELECT, UPDATE, > > DELETE, on one table at time. > > > > > > > > On Tue, Dec 11, 2012 at 2:35 PM, Howard W. Smith, Jr. < > > smithh032...@gmail.com> wrote: > > > >> You're absolutely right, David. Thanks for the response. > >> > >> It is a transaction issue and the @Stateless EJB is holding a > transaction > >> open and writing into 6 to 10 tables in a single database, which is also > >> the database accessed by JSF components (by endusers). The @Stateless > EJB > >> is on a timer ( @Schedule), checks email server for incoming requests > from > >> customers, and takes that data and inserts it into database, so endusers > >> don't have to manually enter the data (that they receive from these > >> formmail results). > >> > >> Below is the exception that I saw maybe an hour or two ago, and I > >> confirmed that it's a locking/transaction issue, and from the > stacktrace, > >> it seems as though the JSF components cannot access the table, that is > >> evidently locked by @Stateless EJB. The @Stateless @EJB updated all > tables > >> on my faster/dev/test server on average of 1 to 2 seconds, and/so in my > >> opinion, the data is not that much at all, maybe a few kbytes of data > being > >> inserted into the database. Anyway, I've been reading up on pessismistic > >> and optimistic locking, and that's where I was in my reading before I > >> noticed your email. I really don't know what the database or JPA is > >> defaulting to, because honestly, I have no code that specifies any > locks. > >> Recently, I only added query hint (readonly) to JPA queries. > Personally, I > >> feel as though I can use 'no locking' for these inserts, since this is > >> brand new data, but the JSF components may be locking the entites/tables > >> during simple queries (SELECT statements). Feel free to change this > >> email/topic to a more suitable topic/subject, if necessary. :) > >> > >> > >> > >> > > -- Jean-Louis