Call Methods Asynchronous in EJB
Asked Answered
R

2

7

I try to save the result of a login process for statistics to the database asynchronously to save time during the login method. But somehow the login process takes longer if i add a thread.sleep to the async method. Why is that? I thought the authenticate method will not wait for the writeResultToStats methode to finish.

    @Stateless
    @LocalBean
    @ConcurrencyManagement(ConcurrencyManagementType.CONTAINER)
    @TransactionManagement(TransactionManagementType.CONTAINER)
    public class CustomerBeanTest {

        @PersistenceContext(unitName = WebPersistenceUnits.QISADS)
        private EntityManager em_local;

        @TransactionAttribute(TransactionAttributeType.NOT_SUPPORTED)
        public void authenticate(Long loginid, String cmppassword) {
            try {
                Login l = em_local.find(Login.class, loginid);
                String s = l.getPassword();
                if (!s.equalsIgnoreCase(cmppassword))
                    throw new PasswordMissmatchException();
                writeResultToStats(loginid, true);
            } catch (PasswordMissmatchException e) {
                writeResultToStats(loginid, false);
            }
        }

        @Asynchronous
        @TransactionAttribute(TransactionAttributeType.REQUIRES_NEW)
        private void writeResultToStats(Long loginID, boolean success) {

            try { // just for testing
                Thread.sleep(10000);
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }

            LogUtils log = new LogUtils(this);
            Login l = em_local.find(Login.class, loginID);
            if (success) {
                l.setSuccessLast(new Date());
                l.setSuccessCount(l.getSuccessCount()+1);
                log.log(Level.INFO, "Update Login Stat Success [%d, %s, %d]", l.getId(), l.getName(), Thread.currentThread().getId());
            } else {
                l.setFailureLast(new Date());
                l.setFailureCount(l.getFailureCount()+1);
                log.log(Level.INFO, "Update Login Stat Fail [%d, %s, %d]", l.getId(), l.getName(), Thread.currentThread().getId());
            }

        }

    }
Rodd answered 28/5, 2013 at 8:47 Comment(2)
I think you need to break out the asynchronous method into another ejb. As it is now, it will just be handled as a local method-invocationPineal
Let me try this and get back to youRodd
P
10

Try to break out the asynchronous method into a separate ejb. Methods invoked from inside the same ejb will be handled just like local method-invocations. The container is not capable of intercept the method call.

EJB-Annotations is only in play when invocation is done by the container.

Alternative

You can have the method in the same EJB but make sure you use the EJB Local interface to lookup the bean and access the methord.

Pineal answered 28/5, 2013 at 9:0 Comment(0)
O
7

Take a look at this example - it shows that You do not need to create separate EJB.

If you have a bean which has both synchronous and asynchronous methods, the asynchronous method cannot be called from within the synchronous one because the container will not intercept it.

But instead of creating another bean, you can call the asynchronous bean method through the SessionContext:

@Stateless
public class OrderProcessorBean {
    @Inject
    SessionContext ctx;
    //synchronous method invoked from EJB call outside this class
    public void synch() {
        //call asynch method
        ctx.getBusinessObject(OrderProcessorBean.class).asynch();
    }

    @Asynchronous
    public void asynch() {
         //asynch logic
    }
}
Overlay answered 15/7, 2013 at 11:34 Comment(1)
Note that link-only answers are discouraged, SO answers should be the end-point of a search for a solution (vs. yet another stopover of references, which tend to get stale over time). Please consider adding a stand-alone synopsis here, keeping the link as a reference.Well

© 2022 - 2024 — McMap. All rights reserved.