7

ログイン方法の時間を節約するために、統計のログイン プロセスの結果を非同期的にデータベースに保存しようとしています。しかし、async メソッドに 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());
            }

        }

    }
4

2 に答える 2

10

非同期メソッドを個別の ejb に分割してみてください。同じ ejb 内から呼び出されたメソッドは、ローカル メソッド呼び出しと同様に処理されます。コンテナーは、メソッド呼び出しをインターセプトできません。

EJB アノテーションは、呼び出しがコンテナーによって行われる場合にのみ機能します。

同じ EJB にメソッドを含めることができますが、EJB ローカル インターフェイスを使用して Bean をルックアップし、メソッドにアクセスするようにしてください。

于 2013-05-28T09:00:03.913 に答える