1

Connection私はかなり標準的な Java ODBC 機能を使用しています。プールから を取得し、 を作成しStatementて実行します。

私たちのユース ケースは、ゲームの進行状況を記録するゲームです。ODBC 呼び出しは、主にストアド プロシージャへの呼び出しであり、ほとんどの場合、戻り値はありません。したがって、ODBC 呼び出しがブロックされるという事実は煩わしいものです。ゲームはすでにターン制になっていますが、DB が遅い場合、ユーザーは一時停止が長くなることがあります。

ODBC 呼び出しの結果を確認する必要がない場合、ステートメントを非同期で実行する組み込み機能はありますか? そうでない場合、多くのコードを書かずにこれを行う良い方法は何ですか? ODBC 例外が発生した場合は、例外をキャッチする必要があります。

この質問は関連しているように見えますが、同一ではありません...非同期のjdbc呼び出しは可能ですか?

4

4 に答える 4

10

あなたが持っていると仮定しましょうOdbcCaller

public class OdbcCaller {

public void callODBC() {
    // call ODBC directly
    // ...
}

実行可能なタスクでラップし、タスクをスレッドプールに送信して、非同期で実行することができます。

public void asyncCallODBC() {
    // wrap the call with a runnable task
    executor.execute(new Runnable() {

        @Override
        public void run() {
            callODBC();
        }
    });
    // the above line would return immediately.
}

これexecutorはJDKによって提供されるスレッドプールの実装であり、次のように定義できます。

Executor executor = new ThreadPoolExecutor(/* core pool size */5,
        /* maximum pool size */10,
        /* keepAliveTime */1,
        /* time unit of keepAliveTime */TimeUnit.MINUTES,
        /* work queue */new ArrayBlockingQueue<Runnable>(10000),
        /* custom thread factory */new ThreadFactory() {
            private AtomicInteger counter = new AtomicInteger(0);

            @Override
            public Thread newThread(Runnable r) {
                Thread t = new Thread(r, "asyncCaller-" + (counter.incrementAndGet()));
                return t;
            }
        },
        /*
         * policy applied when all tasks are occupied and task
         * queue is full.
         */new ThreadPoolExecutor.CallerRunsPolicy());

ThreadPoolExecutor高度に構成可能であり、JavaDocで十分に文書化されているため、最初に読むことをお勧めします。

以下は、私の経験に基づいたスレッドプール構成のいくつかの提案です。

  • 適切なスレッドプールサイズはシナリオによって異なります。調整するためにいくつかのテストを実行する必要がある場合があります。
  • 使用可能なワーカースレッドがない場合、ワークキューはタスクをキャッシュするために使用されます。無制限のキューは、メモリが不足する可能性があるため、お勧めできません。
  • を提供しThreadFactory、スレッドに意味のある名前を付けることをお勧めします。jstack(または他のツールを使用して)スレッドの状態を検査する必要がある場合に非常に役立ちます。
  • 拒否ポリシーは、使用可能なリソースがない場合に適用されます。組み込みポリシー(拒否、破棄、呼び出し元実行、discardOldest)のいずれかを選択するか、独自のポリシーを実装できます。
于 2013-02-23T16:31:56.827 に答える
0

EJB 3.1 を使用している場合は、@StatelessEJB を作成し、いずれかのメソッドをマークできます@Asynchronous。これは、エンタープライズ Java 環境向けのすぐに使えるソリューションです (リソースThreadの外部管理は推奨されません)。

于 2013-02-27T16:41:52.087 に答える
0
public class Snippet
{
    static int i = 0;



    public static void main(String[] args) throws SQLException
    {
        ExecutorService eventExecutor = Executors.newSingleThreadExecutor();
        final Connection c = DriverManager.getConnection("jdbc:url", "user",
                "password");
        Runnable r = new Runnable()
        {

            public void run()
            {
                try
                {
                    CallableStatement s = c
                            .prepareCall("{ call your_procedure(?) }");
                    s.setInt(1, i);
                    s.execute();
                } catch (SQLException e)
                {
                    e.printStackTrace();
                }
            }
        };
        for (; i < 100; i++)
            eventExecutor.submit(r);
    }
}

your_procedure への呼び出しを 100 個の異なるパラメーターで 100 回実行します。

于 2013-02-27T13:45:38.503 に答える
-2

これについてはよくわかりませんが、aynsctask を使用できますか? それは別のスレッドでdbのものを処理します

于 2013-02-19T18:36:09.727 に答える