Использование специальных функций драйвера JDBC с динамическими пулами соединений прокси - PullRequest
0 голосов
/ 02 ноября 2011

Мы оцениваем менеджер транзакций JTA для унаследованного проекта Oracle JDBC и до сих пор изучали Bitronix и Atomikos.

Реализации java.sql.DataSource в пулах соединений Bitronix и Atomikos интенсивно используют динамические прокси-объекты для возвращаемых экземпляров интерфейса JDBC.

PreparedStatements соединений Bitronix PoolingDataSource сами являются динамическими прокси-объектами, приведение их к oracle.jdbc.OraclePreparedStatement приводит к исключению ClassCastException. С другой стороны, прокси-объекты динамического соединения Atomikos возвращают фактические экземпляры OraclePreparedStatement - возможно приведение.

Устаревший код использует Пакетное обновление Oracle JDBC и, следовательно, преобразует java.sql.PreparedStatements в oracle.jdbc.OraclePreparedStatement для вызова OraclePreparedStatement.setExecuteBatch (batchSize). Переход на стандартную пакетную обработку JDBC не возможен.

Как мы должны использовать специальные функции драйвера JDBC, которые требуют доступа к фактическим классам / интерфейсам драйверов в данной ситуации?

Ответы [ 2 ]

1 голос
/ 02 ноября 2011

Если пулы соединений правильно поддерживают интерфейс java.sql.Wrapper, вы можете получить доступ к обернутому объекту, используя метод unwrap.

0 голосов
/ 03 ноября 2011

Спасибо, это действительно работает как для 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.OraclePreparedStatement " SQLException, хотя.
Глядя на источник прокси-класса 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);
...