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