Использование специальных функций драйвера JDBC с динамическими пулами прокси-соединений

#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.