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

Reply via email to