1

こんにちは、Postconstruct で起動し、データベースを定期的に更新する長時間実行スレッドです。

こんな感じ

    public void postconstruct() {
    Runnable runnable;
    runnable = new Runnable() {
        @Override
        public void run() {
            int interval = poissonRandomNumber(15);
            while (true) {
                try {
                    Map<Account, AccountUpdate> recentUpdates =
                            simulator.getRecentUpdates(tickDAO, securityDAO);
                    for (Map.Entry<Account, AccountUpdate> entry : recentUpdates.entrySet()) {
                        Account account = entry.getKey();
                        //                            String realised = getAccountReturn(parts, account);
                        Account accountByName = accountDAO.findAccountByName(account.getName());
                        if( accountByName == null  )
                        {
                            account.setAccountId(null);
                            accountByName = accountDAO.create(account);
                        }
                        int realised = new Random().nextInt(50);
                        boolean nextBoolean = new Random().nextBoolean();
                        realised = nextBoolean == true ? realised : -realised;
                        AccountUpdate accountUpdate = entry.getValue();
                        accountUpdate.setAccountId(accountByName);
                        accountUpdate.setDateCreated(new Date());
                        accountUpdate.setUnRealisedPL(new BigDecimal(realised));
                        accountUpdateDAO.create(accountUpdate);
                    }
                    Thread.sleep(interval);
                } catch (Exception ex) {
                    Logger.getLogger(ApplicationManager.class.getName()).log(Level.SEVERE, null, ex);
                }
            }
        }
    };
    Thread tickThread = new Thread(runnable);
    tickThread.start();

アプリケーションを起動するたびに、コンテナの準備ができていないように見えるため、多くの例外が発生します

DAO の最適な使用方法と、conytainer の準備ができているかどうかを検出する方法を知る必要があります

例外は次のとおりです。

SEVERE: java.lang.NullPointerException
at com.sun.ejb.containers.util.pool.NonBlockingPool.returnObject(NonBlockingPool.java:285)
at com.sun.ejb.containers.StatelessSessionContainer.releaseContext(StatelessSessionContainer.java:602)
at com.sun.ejb.containers.BaseContainer.postInvoke(BaseContainer.java:2055)
at com.sun.ejb.containers.BaseContainer.postInvoke(BaseContainer.java:1994)
at com.sun.ejb.containers.EJBLocalObjectInvocationHandler.invoke(EJBLocalObjectInvocationHandler.java:222)
at com.sun.ejb.containers.EJBLocalObjectInvocationHandlerDelegate.invoke(EJBLocalObjectInvocationHandlerDelegate.java:89)
at $Proxy270.create(Unknown Source)
at ucl.atrade.rnpvms.server.services.ApplicationManager$1.run(ApplicationManager.java:126)
at java.lang.Thread.run(Thread.java:722)

SEVERE: javax.ejb.EJBException: Attempt to invoke when container is in Undeployed
    at com.sun.ejb.containers.BaseContainer.postInvoke(BaseContainer.java:1999)
    at com.sun.ejb.containers.BaseContainer.postInvoke(BaseContainer.java:1994)
    at com.sun.ejb.containers.EJBLocalObjectInvocationHandler.invoke(EJBLocalObjectInvocationHandler.java:222)
    at com.sun.ejb.containers.EJBLocalObjectInvocationHandlerDelegate.invoke(EJBLocalObjectInvocationHandlerDelegate.java:89)
    at $Proxy265.findSecurityBySymbol(Unknown Source)
    at ucl.atrade.rnpvms.server.datafeed.AccountUpdateSimulator.getRecentUpdates(AccountUpdateSimulator.java:74)
    at ucl.atrade.rnpvms.server.services.ApplicationManager$1.run(ApplicationManager.java:108)
    at java.lang.Thread.run(Thread.java:722)
4

1 に答える 1

2

このリンクでよく説明されているように、

EJB 仕様では、スレッドを管理する責任を EJB コンテナーに割り当てます。エンタープライズ Bean インスタンスがスレッドを作成および管理できるようにすると、コンポーネントのライフサイクルを制御するコンテナーの機能が妨げられます。

これはRunnable、EJB での使用は適切ではないことを意味します。

特定の頻度でコードを実行したい場合は、Timer Serviceを使用できます。

逆に、データベースへの更新が行われたときに何らかのコードを実行する必要がある場合、つまり非同期に実行する必要がある場合は、JMS、データベース トリガー、Persistence Context 共有/伝播、Entity Listenersなどの他の手法を使用する必要があります。アプリケーションの要件。

于 2012-08-16T09:37:42.827 に答える