setAutoCommit(false)不使用c3p0

时间:2013-07-04 08:13:28

标签: postgresql jetty connection-pooling c3p0

我正在使用postgresql 9.2和C3p0 0.9.2.1,我创建了一个连接自定义程序来禁用autoCommit并设置transactionMode但是当我在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 auto commit mode is disabled为什么c3p0会自动激活它?我应该将forceIgnoreUnresolvedTransactions设置为true吗?

编辑:每当我在检索数据源后提交事务时,都会收到此错误:

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

1 个答案:

答案 0 :(得分:6)

JDBC spec表示“默认是在创建Connection对象时启用自动提交模式。”无论数据库在其他上下文中的行为如何,这都是跨DBMS默认值。除非明确调用setAutoCommit( false ),否则JDBC程序员可能依赖于autoCommit的设置。 c3p0尊重这一点。

c3p0允许ConnectionCustomizers在指定无单一行为时持久覆盖onAcquire()方法中的连接默认值。例如,规范声明“Connection对象的默认事务级别由驱动程序确定 提供连接。“因此,对于transactionIsolation,如果你在onAcquire(...)中重置,c3p0将记住你选择的默认值,并且总是在checkout之前将transactionIsolation恢复到该默认值。但是,c3p0明确不允许您可以在autoCommit中禁用onAcquire(...),并在默认情况下禁用autoCommit。在退房时,c3p0坚持要求符合规范的连接。

您可以通过覆盖onCheckOut(...)方法获得所需的行为。当调用onCheckOut(...)时,Connection已经签出,你可以在那里做任何你想做的事情,c3p0已经用尽了它对规范之神的义务。如果您希望客户始终看到非自动提交连接,请在setAutoCommit( false )中致电onCheckOut(...)。但请注意,这会使您的客户端代码无法移植。如果你离开c3p0并切换到另一个数据源,你将需要使用一些其他特定于库的方法来始终禁用autoCommit,否则你会发现你的应用程序行为不端。因为即使对于postgres,JDBC Connections默认为autoCommit

注意:其值不是由规范修复的连接属性可以onAcquire(...)方法catalog方法持续覆盖,holdabilitytransactionIsolationreadOnlytypeMapforceIgnoreUnresolvedTransactions

P.S。 true设置为{{1}}。育。