2013-02-19 1 views
1

Я использую довольно стандартную функциональность Java ODBC - захватите Connection из пула, создайте Statement и выполните его.Неблокирующие вызовы ODBC в Java

Наш прецедент - игра, протоколирование игры - вызовы ODBC - это в основном вызовы хранимых процедур, и в большинстве случаев нет возвращаемых значений. Таким образом, блоки вызовов ODBC раздражают - игра уже основана на поворотах, но пользователи могут видеть более длинные паузы, если БД медленно.

Если мне не нужно проверять результат вызова ODBC, есть ли встроенная функция для выполнения оператора асинхронно? Если нет, то, что это хороший способ сделать это, не написав много кода? Мне все еще нужно ломать исключения ODBC, когда и когда они происходят.

Этот вопрос выглядит связаны, хотя и не тождественны ... Is asynchronous jdbc call possible?

+0

Почему бы не выполнить вызовы JDBC в отдельном «потоке»? –

+0

Это вопрос.Если вы считаете, что это лучший подход, пожалуйста, укажите пример, как запустить существующий блок JDBC-кода в потоке. –

+0

Хотел бы ответить, но сначала - используете ли вы JDBC для подключения к источнику данных ODBC (драйвер JDBC типа 1, также известный как мост JDBC-ODBC)? Является ли ваш источник данных MS Access или подобным? –

ответ

9

Предположим, у вас есть 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, вы можете сначала прочитать его.

Ниже приведены некоторые sugguestion резьбовых конфигураций бассейнов на основе моего опыта:

  • Правильный размер пула потоков зависит от сценария, возможно, потребуется выполнить некоторые тесты, чтобы настроить его.
  • Рабочая очередь используется для кэширования задач, когда нет доступных рабочих потоков. Неограниченная очередь не является хорошей идеей, так как вы можете исчерпать свою память.
  • Это хорошая практика, чтобы предоставить ThreadFactory и дать потокам значимое имя. Это будет очень полезно, когда вам нужно проверить состояния потоков (используя jstack или другие инструменты).
  • Политика отклонения применяется, когда ресурсы отсутствуют. Вы можете выбрать одну из встроенных политик (reject, discard, caller-run, discardOldest) или реализовать свою собственную политику.
+0

Таким образом, каждый метод моего класса DAO должен быть преобразован в отдельный класс OdbcCaller. Невозможно просто обернуть вызов метода с помощью делегата, подобного C#, или чего-нибудь еще? –

+0

Вы можете использовать 'AOP', чтобы избежать создания класса каждого класса DAO, посмотрите [этот пост] (http://stackoverflow.com/questions/325640/aspect-oriented-programming-in-java) – ericson

-2

Не уверен, что это возможно, но вы можете использовать aynsctask? Это обрабатывает дб материал в другом потоке

+0

Когда я ищу 'aynsctask' Я получаю только результаты для Android. Является ли это классом Java-6 или общим термином? –

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 различными параметрами.

0

Если вы используете EJB 3.1, вы можете создать EJB @Stateless и отметить один из методов @Asynchronous. Это готовое решение для среды Enterprise Java (Там внешнее управление Thread ресурсов не рекомендуется).

+0

Обычный Java Я боюсь - это серверное приложение, а не веб-приложение. –

+0

В чем разница между HTTP-сервером и webapp? – AnthonyJClink