On Dec 13, 2012, at 1:53 PM, David Blevins <david.blev...@gmail.com> wrote:

> 
> On Dec 13, 2012, at 1:17 PM, "Howard W. Smith, Jr." <smithh032...@gmail.com> 
> wrote:
> 
>> David,
>> 
>> 1. definitely not using @Asynchronous; that was no good at all
>> 
>> 2. Actually, it was 2 seconds on the Windows Server 2008 64-bit 16GB RAM...
>> always
>> 
>> 3. Always 5 to 10 minutes to process 1 or 2 emails on Windows Server 2003
>> 32-bit 4GB RAM
> 
> Good info thanks.
> 
>> 4. As noted on the JIRA, I tried the TransactionAttribute NEVER and
>> REQUIRES_NEW on @Stateless EJB that was all invoked via @Schedule, and same
>> test results, which are.... The EJB timer rolls back the transaction, and
>> every database operation that the EmailStatelessBean completed...prior to
>> @Schedule rolling back the transaction.
> 
> Right, that suggestion was never implemented as it was intended.  Changing 
> the TransactionAttribute alone will do nothing.  What we need is to 1) 
> prevent a transaction from being started and 2) creating a new and smaller 
> transaction scope through a small code rework.
> 
> The ApplicationScoped check backfired because it has the effect of locking 
> tables for much longer.  We want to process each "email" in an individual 
> transaction and move away from one big transaction.  This is really the most 
> critical step to take, no other steps or workarounds matter at this phase of 
> the problem.
> 
> Let's try this:
> 
>  - Go back to the very original 5-10 minutes 32-bit code
> 
>  - Split EmailSessionBean into two beans
> 
>      - EmailSessionBean
>         - will be marked @TransactionAttribute(NEVER)
>         - will no longer have an @PersistenceContext EntityManager reference
>      - AirportShuttleRequestProcessorBean
>         - will be marked @TransactionAttribute(REQUIRES_NEW)
>         - will have only one public method, `createOrderForAirportShuttle`
>         - will do all persistence processing
> 
> The EmailSessionBean will have an @EJB reference to the new 
> AirportShuttleRequestProcessorBean.  Effectively, we're splitting the code 
> that does the contacting the of the email server from the code that contacts 
> the database and we're creating several much smaller transactions.

And one more tweak.  Let's change the EmailSessionBean to type @Singleton and 
add @Lock(WRITE) to our `getEmails()` method.

We're doing this to ensure that two `getEmail()` invocations cannot possibly 
happen at the same time.  This is not necessarily the case now, but this can 
easily occur if the `getEmails()` method takes longer than the configured time 
of every 10 minutes.  It can also occur if the time gets shorted, to say 2 
minutes.

With switching our EmailSessionBean bean to type @Singleton and ensuring 
@Lock(WRITE) on the `getEmails()` method, once things are working well we could 
effectively dramatically reduce the delay between firings to something far more 
aggressive than 10 minutes (say 2 or 5 minutes) and still be safe.  The 
combination of @Singleton/@Lock(WRITE) guarantees that method will only ever be 
active one-at-a-time in the entire application.


-David

Reply via email to