#java #jdbc #casting #connection-pooling
#java #jdbc #Кастинг #объединение пулов соединений
Вопрос:
Мы оцениваем диспетчер транзакций JTA для устаревшего проекта Oracle JDBC и до сих пор рассматривали Bitronix и Atomikos.
Реализации java.sql.DataSource пулов соединений Bitronix и Atomikos активно используют динамические прокси-объекты для возвращаемых экземпляров интерфейса JDBC.
Подготовленные состояния подключений Bitronix PoolingDataSource сами по себе являются динамическими прокси-объектами, которые преобразуются в oracle.jdbc.OraclePreparedStatement приводит к исключению ClassCastException. С другой стороны, объекты прокси-сервера динамического подключения Atomikos возвращают фактические экземпляры OraclePreparedStatement — возможно приведение.
Устаревший код использует пакетное обновление Oracle JDBC и, следовательно, преобразует java.sql.PreparedStatements в oracle.jdbc.OraclePreparedStatement для вызова OraclePreparedStatement.setExecuteBatch(размер пакета). Переключение на стандартную пакетную обработку JDBC не является вариантом.
Как мы должны использовать специальные функции драйвера JDBC, которые требуют доступа к фактическим классам / интерфейсам драйверов в данной ситуации?
Ответ №1:
Если пулы подключений java.sql.Wrapper
правильно поддерживают интерфейс, вы можете получить доступ к обернутому объекту с помощью unwrap
метода.
Ответ №2:
Спасибо, это действительно работало как для Bitronix 2.1.2, так и для Atomikos 3.7.0 — при условии, что причиной был драйвер Oracle JDK6.
Я тестировал unwrap(oracle.jdbc.OraclePreparedStatement.class)
раньше, начиная с oracle.jdbc.OraclePreparedStatement — это интерфейс для классов PreparedStatement драйвера. Я получил «bitronix.tm.resource.jdbc.JdbcUncachedPreparedStatementHandle не является оболочкой для интерфейса oracle.jdbc.driver.Однако исключение SQLException» OraclePreparedStatement».
Смотрим на источник прокси-класса Bitronix (JdbcUncachedPreparedStatementHandle) Я нашел:
public Object unwrap(Class iface) throws SQLException {
if (PreparedStatement.class.equals(iface)) {
return delegate;
}
throw new SQLException(getClass().getName() " is not a wrapper for interface " iface.getName());
}
Разве это не должно быть
public Object unwrap(Class iface) throws SQLException {
if (iface.isAssignableFrom(delegate.getClass()) {
return delegate;
}
throw new SQLException(getClass().getName() " is not a wrapper for interface " iface.getName());
}
?
В любом случае — когда я использую этот код, он работает как для Bitronix, так и для Atomikos — Atomikos в любом случае не является проблемой, поскольку возвращаемый PreparedStatement не является прокси-объектом, как упоминалось выше.
((OraclePreparedStatement)pstmt.unwrap(PreparedStatement.class)).setExecuteBatch(100);
Комментарии:
1. Я открыл jira.codehaus.org/browse/BTM-114 чтобы отследить это, и теперь исправлено. Спасибо, что указали на это, хотя было бы эффективнее сообщить о проблеме непосредственно в списке рассылки BTM.