调用EJB中的异步方法

Has*_*cay 6 asynchronous java-ee ejb-3.0 ejb-3.1 glassfish-3

我尝试异步保存统计信息登录过程的结果到数据库,以节省登录方法的时间.但是如果我向异步方法添加thread.sleep,登录过程会花费更长的时间.这是为什么?我认为authenticate方法不会等待writeResultToStats方法完成.

    @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());
            }

        }

    }
Run Code Online (Sandbox Code Playgroud)

Aks*_*ert 10

尝试将异步方法分解为单独的ejb.从同一ejb内部调用的方法将像本地方法调用一样处理.容器无法拦截方法调用.

EJB-Annotations仅在容器完成调用时才起作用.

替代

您可以在同一EJB中使用该方法,但请确保使用EJB Local接口查找bean并访问methord.


jig*_*gga 7

看一下这个例子 - 它表明你不需要创建单独的EJB.

如果您的bean具有同步和异步方法,则无法从同步方法中调用异步方法,因为容器不会拦截它.

但是不是创建另一个bean,而是可以通过SessionContext调用异步bean方法:

@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
    }
}
Run Code Online (Sandbox Code Playgroud)

  • 请注意,不建议使用仅链接答案,因此,答案应该是搜索解决方案的终点(相对于引用的另一个中途停留,随着时间推移会逐渐变得陈旧).请考虑在此处添加独立的概要,并将链接作为参考. (2认同)