jakarta-ee - EJB 中的异步调用方法

标签 jakarta-ee asynchronous ejb-3.0 glassfish-3 ejb-3.1

我尝试将用于统计的登录过程的结果异步保存到数据库中,以节省登录方法期间的时间。但是,如果我将 thread.sleep 添加到异步方法中,登录过程会以某种方式花费更长的时间。这是为什么?我认为身份验证方法不会等待 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());
            }

        }

    }

最佳答案

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

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

选择

您可以在同一个 EJB 中拥有该方法,但请确保使用 EJB Local 接口(interface)来查找 bean 并访问该方法。

关于jakarta-ee - EJB 中的异步调用方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16787701/

相关文章:

asynchronous - 关于异步编程设计模式的资源

c# - 在 ASP.NET 中异步发送电子邮件的正确方法...(我做对了吗?)

java - 无法在 Jboss 6 上部署 Maven jar (MDB)

java - 如何将war文件部署者的第三方类加载到tomcat中

java - JMS:MessageListener的onMessage中消息可以为空吗?

java - 警告 : Unknown version string [3. 1]。将使用默认版本

jakarta-ee - Jersey:在不使用 web.xml 文件的情况下禁用 OPTIONS 请求的自动 Wadl 生成?

objective-c - block 和异步回调,dealloc 对象 - 需要 nil block

java - 使用自己的注释更改查看实体 Bean 值的方式

java - 我无法设置我的 jndi.properties 来访问 Jboss 5 上的远程 EJB