3

私はpostgresql 9.2およびC3p0 0.9.2.1を使用しており、無効にして設定する接続カスタマイザーを作成しましたがautoCommittransactionMode検索を行っInitialContextて. 自動コミットを無効にするにはどうすればよいですか?dataSourceautoCommit

接続カスタマイザー:

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);
    }
}

DAO のデータソースを取得するクラス:

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 に設定する必要がありますか?

編集:データソースを取得した後にトランザクションをコミットするたびに、次のエラーが発生します:

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

4

1 に答える 1

7

JDBC 仕様には、「デフォルトでは、Connection オブジェクトの作成時に自動コミット モードが有効になる」と記載されています。これは、データベースが他のコンテキストでどのように動作するかに関係なく、クロス DBMS のデフォルトです。JDBC プログラマーは、明示的に を呼び出さない限り、設定されている autoCommit に依存する場合がありますsetAutoCommit( false )。c3p0 はこれを尊重します。

onAcquire()c3p0 では、単一の動作が指定されていない場合に、ConnectionCustomizers がメソッド内の Connection のデフォルトを永続的にオーバーライドできます。たとえば、仕様には、「接続オブジェクトのデフォルトのトランザクション レベルは、接続を提供するドライバーによって決定される」と記載されています。そのため、transactionIsolation を でリセットするとonAcquire(...)、c3p0 は選択したデフォルトを記憶し、チェックアウト前に常に transactionIsolation をそのデフォルトに戻します。ただし、c3p0 は明示的にautoCommit一度無効にすることを許可せず、デフォルトで無効になっonAcquire(...)autoCommitいます。チェックアウトの時点で、c3p0 は仕様に準拠した接続を使用していると主張します。

メソッドをオーバーライドすることで、必要な動作を取得できますonCheckOut(...)。が呼び出された時点で接続はすでにチェックアウトされてonCheckOut(...)おり、そこでやりたいことは何でもできます。c3p0 は、その時点で仕様の神に対する義務を果たしています。クライアントに非 autoCommit 接続を常に表示させたい場合は、 を呼び出しsetAutoCommit( false )ますonCheckOut(...)。ただし、これによりクライアント コードが移植できなくなることに注意してください。c3p0 を離れて別の DataSource に切り替える場合は、他のライブラリ固有の手段を使用して常に無効にするautoCommit必要があります。そうしないと、アプリケーションが誤動作することがわかります。postgres の場合でも、JDBC 接続はautoCommitデフォルトであるからです。

注:onAcquire(...)仕様によって値が固定されていないため、メソッドで永続的にオーバーライドできる Connection プロパティはcatalogholdabilitytransactionIsolationreadOnly、およびtypeMapです。

psに設定しないでください。ユク。forceIgnoreUnresolvedTransactionstrue

于 2013-07-04T09:06:01.633 に答える