Подтвердить что ты не робот

OracleDataSource против Oracle UCP PoolDataSource

Я изучал некоторые элементы JDBC Oracle Connection Pooling и наткнулся на новую (er) реализацию пула Oracle, называемую Universal Connection Pool (UCP). Теперь для этого используется новый класс PoolDataSource для пула соединений, а не OracleDataSource [с включенным параметром кеша]. Я обсуждаю, следует ли переключиться на эту новую реализацию, но не может найти хорошую документацию о том, что (если есть), исправления/обновления, это купило бы меня. У кого-нибудь есть опыт работы с обоими? Плюсы/минусы? Спасибо.

4b9b3361

Ответ 1

В последнем явном ядре Oracle jdbc (11.2.0.1.0) указано, что кэш Oracle неявного подключения (который используется с OracleDataSource) устарел:

Oracle JDBC Drivers выпускает версию 11.2.0.1.0 Readme.txt

Что нового в этой версии?

Универсальный пул соединений    В этом выпуске функция кэширования неявных подключений Oracle    осуждается. Пользователям настоятельно рекомендуется использовать новый универсальный    Пул соединений. UCP имеет все особенности    ICC, плюс многое другое. UCP доступен в отдельном файле jar,    ucp.jar.

Итак, я думаю, что лучше начать использовать UCP, но документация не так уж хороша. Например, я не хотел использовать UCP с помощью spring...

UPDATE: Я нашел правильную конфигурацию spring: ОК Я понимаю, что нашел правильную конфигурацию:

<bean id="dataSource" class="oracle.ucp.jdbc.PoolDataSourceFactory" factory-method="getPoolDataSource">
    <property name="URL" value="jdbc:oracle:thin:@myserver:1521:mysid" />
    <property name="user" value="myuser" />
    <property name="password" value="mypassword" />
    <property name="connectionFactoryClassName" value="oracle.jdbc.pool.OracleDataSource" />
    <property name="connectionPoolName" value="ANAG_POOL" />
    <property name="minPoolSize" value="5" />
    <property name="maxPoolSize" value="10" />
    <property name="initialPoolSize" value="5" />
    <property name="inactiveConnectionTimeout" value="120" />
    <property name="validateConnectionOnBorrow" value="true" />
    <property name="maxStatements" value="10" />
</bean>

Ключ должен указать правильный класс factory и правый factory метод

Ответ 2

PDS является "универсальным", поскольку он обеспечивает тот же уровень возможностей объединения, который вы получаете в ODS для баз данных, отличных от Oracle. MySQL.

См. Руководство для разработчиков UCP, статья о веб-сайте Oracle и Руководство по переходу UCP

Я не вижу каких-либо непосредственных преимуществ перехода на UCP (PDS) из ODS, но, возможно, в будущем Oracle откажется от некоторых функций в ODS. Я использовал ODS какое-то время, и пока я доволен этим, но если бы я начал новый, я бы пошел с PDS.

Ответ 4

Я протестировал UCP и развернул ее для производства в приложении Spring 3.0.5 Hibernate, используя Spring JMS-контейнеры-слушатели и Spring -управленные сеансы и транзакции, используя аннотацию @Transactional. Данные иногда вызывают ошибки ограничения SQL, из-за отдельных потоков прослушивателя, пытающихся обновить одну и ту же запись. Когда это происходит, исключение генерируется одним методом, аннотированным @Transactional, и ошибка регистрируется в базе данных другим методом, аннотированным @Transactional. По какой-то причине этот процесс, по-видимому, приводит к утечке курсора, что в конечном итоге добавляет и запускает превышение предела открытого курсора ORA-01000, что приводит к тому, что поток перестает обрабатывать что-либо.

OracleDataSource, работающий в том же коде, похоже, не теряет курсоров, поэтому он не вызывает этой проблемы.

Это довольно странный сценарий, но он указывает мне, что слишком рано использовать UCP в приложении с такой структурой.

Ответ 5

Я тоже тестирую UCP и обнаруживаю, что у меня проблемы с производительностью в приложении на основе пула потоков. Первоначально я пробовал OracleDataSource, но у меня проблемы с настройкой его для пакетной обработки. Я продолжаю получать NullPointerExceptions в соединениях, заставляя меня полагать, что у меня какая-то утечка соединения, но только с некоторым приложением, есть другие приложения, которые мы управляем, которые не являются пакетными процессами, которые OracleDataSource работает хорошо.

Основываясь на этом сообщении и нескольких других, я нашел исследование этой темы, я попробовал UCP. Я обнаружил, что с достаточной настройкой я мог избавиться от закрытых соединений /NullPointerExceptions при ошибках стиля соединений, но Garbage Collection принимала побои. Долгосрочный GC заполняется быстро и никогда не появляется, пока приложение не закончит работу. Иногда это может занять до одного дня или больше, если нагрузка действительно тяжелая. Я также замечаю, что для обработки данных требуется еще больше времени. Я сравниваю это с ныне обесцененным классом OracleCacheImpl (который мы в настоящее время используем в производстве, потому что он все еще "работает просто" ), где он использовал третью память GC, которую делает UCP, и обрабатывает файлы намного быстрее. Во всех других приложениях UCP, похоже, работает очень хорошо и обрабатывает практически все, что я бросаю на него, но приложение пула потоков является основным приложением, и я не мог рисковать исключениями GC в производстве.

Ответ 6

Я пробовал ucp и производительность лучше... Может быть, ключ использует этот

oracle.ucp.jdbc.PoolDataSource ds = (oracle.ucp.jdbc.PoolDataSource)envContext.lookup(url_r);
MyConnectionLabelingCallback callback = new MyConnectionLabelingCallback();
ds.registerConnectionLabelingCallback( callback );


Properties label = new Properties();
label.setProperty(pname, KEY);
conn = ds.getConnection(label);

Это помогает заимствовать соединение и никогда не закрывать его. Таким образом, производительность отличная

Код для класса обратного вызова

открытый класс MyConnectionLabelingCallback реализует ConnectionLabelingCallback {

  public MyConnectionLabelingCallback()
  {
  }

  public int cost(Properties reqLabels, Properties currentLabels)
  {

    // Case 1: exact match
    if (reqLabels.equals(currentLabels))
    {
      System.out.println("## Exact match found!! ##");
      return 0;
    }

    // Case 2: some labels match with no unmatched labels
    String iso1 = (String) reqLabels.get("TRANSACTION_ISOLATION");
    String iso2 = (String) currentLabels.get("TRANSACTION_ISOLATION");
    boolean match =
      (iso1 != null && iso2 != null && iso1.equalsIgnoreCase(iso2));
    Set rKeys = reqLabels.keySet();
    Set cKeys = currentLabels.keySet();
    if (match && rKeys.containsAll(cKeys))
    {
      System.out.println("## Partial match found!! ##");
      return 10;
    }

    // No label matches to application preference.
    // Do not choose this connection.
    System.out.println("## No match found!! ##");
    return Integer.MAX_VALUE;
  }

  public boolean configure(Properties reqLabels, Object conn)
  {

      System.out.println("Configure################");
    try
    {
      String isoStr = (String) reqLabels.get("TRANSACTION_ISOLATION");
      ((Connection)conn).setTransactionIsolation(Integer.valueOf(isoStr));
      LabelableConnection lconn = (LabelableConnection) conn;

      // Find the unmatched labels on this connection
      Properties unmatchedLabels =
       lconn.getUnmatchedConnectionLabels(reqLabels);

      // Apply each label <key,value> in unmatchedLabels to conn
      for (Map.Entry<Object, Object> label : unmatchedLabels.entrySet())
      {
        String key = (String) label.getKey();
        String value = (String) label.getValue();
        lconn.applyConnectionLabel(key, value);
      }
    }
    catch (Exception exc)
    {

      return false;
    }
    return true;
  }
}

Ответ 7

Существует два возможных способа использования UCP в Spring Bean.xml.

Для db.properties, заданного некоторым файлом, затем загрузите это, затем используйте один из них:

<bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">

    <property name="location">
        <value>classpath:resources/db.properties</value>
    </property>
</bean>

Первый из них: oracle.ucp.jdbc.PoolDataSourceImpl: -

<bean id="dataSource" class="oracle.ucp.jdbc.PoolDataSourceImpl">

    <property name="URL" value="${jdbc.url}" />
    <property name="user" value="${jdbc.username}" />
    <property name="password" value="${jdbc.password}" />

    <property name="validateConnectionOnBorrow" value="true"/>

    <property name="connectionFactoryClassName" value="oracle.jdbc.pool.OracleDataSource" />
    <property name="connectionPoolName" value="TEST_POOL" />
    <property name="minPoolSize" value="10" />
    <property name="maxPoolSize" value="20" />
    <property name="initialPoolSize" value="12" />
</bean>

Второй с oracle.ucp.jdbc.PoolDataSourceFactory: -

 <bean id="dataSource" class="oracle.ucp.jdbc.PoolDataSourceFactory"  
     factory-method="getPoolDataSource">        
    <property name="URL" value="${jdbc.url}" />
    <property name="user" value="${jdbc.username}" />
    <property name="password" value="${jdbc.password}" />

    <property name="validateConnectionOnBorrow" value="true"/>

    <property name="connectionFactoryClassName" value="oracle.jdbc.pool.OracleDataSource" />
    <property name="connectionPoolName" value="TEST_POOL" />
    <property name="minPoolSize" value="10" />
    <property name="maxPoolSize" value="20" />
    <property name="initialPoolSize" value="12" />
</bean>

Что это:) Вот ссылка на подробную документацию: https://docs.oracle.com/cd/E11882_01/java.112/e12265/connect.htm#CHDDCICA

Ответ 8

Неявное кеширование соединений выполняется немного лучше, чем UCP, если вы используете проверку соединения. Это соответствует ошибке 16723836, которая должна быть исправлена ​​в 12.1.0.2.

Объединение UCP становится все более дорогостоящим для получения/возврата при увеличении параллельной нагрузки. Тест сравнивает оракул неявное кеширование соединений, объединение котировок и UCP. Все 3 сконфигурированный для обеспечения максимально 200 соединений, минимум 20 соединений и начальный размер 2. Все 3 настроены для проверки соединений как они удаляются из бассейна. В пуле tomcat используется оператор "select sysdate from dual "для проверки.

Эти результаты на 64-битном RedHat node с 64 логическими ядрами (32 физических) и 128 ГБ оперативной памяти.

В 5 параллельных потоках UCP является самым медленным, но полным управлением соединениями время (получение и закрытие) в среднем составляет менее 1 мс. По мере увеличения concurrency UCP падает все дальше и дальше позади другие решения:

25 Threads:
Implicit: 0.58ms
Tomcat: 0.92ms
UCP: 1.50ms

50 Threads:
Implicit: 0.92ms
Tomcat: 1.60ms
UCP: 6.80ms

100 Threads:
Implicit: 2.60ms
Tomcat: 3.20ms
UCP: 21.40ms

180 Threads:
Implicit: 13.86ms
Tomcat: 15.34ms
UCP: 40.70ms