setAutoCommit (false) не работает с c3p0


Я работаю с postgresql 9.2 и C3p0 0.9.2.1, и я создал настройщик соединений, чтобы отключить autoCommit и установить transactionMode, но когда я делаю поиск по InitialContext, чтобы получить dataSource, autoCommit не отключается при подключении (журнал внизу). Как отключить автоматическую фиксацию ?

Настройка Соединения:

public class IsolationLevelConnectionCustomizer extends
        AbstractConnectionCustomizer {

    @Override
    public void onAcquire(Connection c, String parentDataSourceIdentityToken)
            throws Exception {
        super.onAcquire(c, parentDataSourceIdentityToken);
        System.out.println("Connection acquired, set autocommit off and repeatable read transaction mode.");
        c.setAutoCommit(false);
        c.setTransactionIsolation(Connection.TRANSACTION_REPEATABLE_READ);
    }
}

Класс для извлечения источника данных для DAOs:

public class DAOAcquire {
    private ComboPooledDataSource m_cpdsDataSource = null;
    private static final String LOOKUP_CONNECT = "jdbc/mydb";

    public DAOAcquire() throws NamingException {
        InitialContext context = new InitialContext();
        m_cpdsDataSource = (ComboPooledDataSource) context.lookup(LOOKUP_CONNECT);

        if (m_cpdsDataSource != null) {
            try {
                System.out.println("Autocommit = "+String.valueOf(m_cpdsDataSource.getConnection().getAutoCommit()));

            } catch (SQLException e) {
                System.out.println("Could not get autocommit value : "+e.getMessage());
                e.printStackTrace();
            }
        }
    }

    public ComboPooledDataSource getComboPooledDataSource() {
        return m_cpdsDataSource;
    }

    /**
     * @return the jdbcTemplate
     * @throws NamingException 
     */
    public JdbcTemplate getJdbcTemplate() throws NamingException {
        return new JdbcTemplate(m_cpdsDataSource);
    }

    /**
     * Commit transactions
     * @throws SQLException
     */
    public void commit() throws SQLException {
        if (m_cpdsDataSource != null) {
            m_cpdsDataSource.getConnection().commit();
        } else {
            throw new SQLException("Could not commit. Reason : Unable to connect to database, dataSource is null.");
        }
    }

    /**
     * rollback all transactions to previous save point
     * @throws SQLException
     */
    public void rollback() throws SQLException {
        if (m_cpdsDataSource != null) {
            m_cpdsDataSource.getConnection().rollback();
        } else {
            throw new SQLException("Could not rollback. Reason : Unable to connect to database, dataSource is null.");
        }
    }
}

Журнал :

Connection acquired, set autocommit off and repeatable read transaction mode.
Connection acquired, set autocommit off and repeatable read transaction mode.
Connection acquired, set autocommit off and repeatable read transaction mode.
Autocommit = true

По умолчанию, режим автоматической фиксации postgresql отключен Так почему же c3p0 активировать его автоматически ? Должен ли я установить forceIgnoreUnresolvedTransactions в true ?

EDIT: всякий раз, когда я совершаю транзакцию после получения источника данных, я получаю эту ошибку:

org.postgresql.util.PSQLException: Cannot commit when autoCommit is enabled.

1 2

1 ответ:

СпецификацияJDBC гласит, что "по умолчанию режим автоматической фиксации должен быть включен при создании объекта соединения."Это кросс-СУБД по умолчанию, независимо от того, как база данных ведет себя в других контекстах. Программисты JDBC могут полагаться на установку autoCommit, если они явно не вызывают setAutoCommit( false ). c3p0 чтит это.

C3p0 позволяет ConnectionCustomizers постоянно переопределять значения по умолчанию соединения в методе onAcquire(), когда не задано ни одного поведения. Например, спецификация утверждает, что " уровень транзакции по умолчанию для объекта соединения определяется драйвером обеспечение связи."Итак, для transactionIsolation, если вы сбросите это в onAcquire(...), c3p0 будет помнить выбранный вами дефолт и всегда восстанавливать транзакцию обратно к этому дефолту до проверки. Однако c3p0 явно не позволит Вам отключить autoCommit один раз в onAcquire(...) и по умолчанию отключить autoCommit. в момент выезда c3p0 настаивает на том, что у вас есть спецификация конформная связь.

Вы можете получить желаемое поведение, переопределив метод onCheckOut(...). Соединение уже проверено, когда вызывается onCheckOut(...), Вы можете делать там все, что хотите, c3p0 исчерпал свои обязательства перед богами спецификации в этот момент. Если вы хотите, чтобы ваши клиенты всегда видели неавтоматизированные соединения, вызовите setAutoCommit( false ) в onCheckOut(...). Но имейте в виду, что это делает ваш клиентский код не переносимым. Если вы покинете c3p0 и переключитесь на другой источник данных, вам потребуется используйте какой-нибудь другой библиотечный способ всегда отключать autoCommit, иначе вы обнаружите, что ваше приложение плохо себя ведет. Потому что даже для postgres, соединения JDBC являются autoCommit по умолчанию.

Примечание: свойства соединения, значения которых не фиксируются спецификацией и поэтому могут быть постоянно переопределены в методе onAcquire(...), являются catalog, holdability, transactionIsolation, readOnly, и typeMap.

P. s. Не установить forceIgnoreUnresolvedTransactions в true. гогот.