setAutoCommit(false)不使用c3p0

Jer*_*ith 3 postgresql connection-pooling jetty 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);
    }
}
Run Code Online (Sandbox Code Playgroud)

用于检索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.");
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

记录:

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
Run Code Online (Sandbox Code Playgroud)

默认情况下,postgresql自动提交模式被禁用,为什么c3p0会自动激活它?我应该将forceIgnoreUnresolvedTransactions设置为true吗?

编辑:每当我检索数据源后提交一个事务,我收到此错误:

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

Ste*_*man 6

JDBC规范指出,"默认是自动提交模式下创建的连接对象时也将启用." 无论数据库在其他上下文中的行为如何,这都是跨DBMS默认值.除非明确调用,否则JDBC程序员可能依赖于autoCommit的设置setAutoCommit( false ).c3p0很荣幸这一点.

onAcquire()当指定no single behavior时,c3p0允许ConnectionCustomizers持久覆盖方法中的Connection默认值.例如,规范声明"Connection对象的默认事务级别由提供连接的驱动程序确定." 因此,对于transactionIsolation,如果将其重置onAcquire(...),c3p0将记住您选择的默认值,并始终在checkout之前将transactionIsolation恢复为该默认值.但是,c3p0明确不允许您禁用autoCommit一次onAcquire(...)autoCommit默认禁用.在退房时,c3p0坚持要求符合规范的连接.

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

注意:连接属性,其值不是由规格固定,因此可以在被持久地重写onAcquire(...)方法是catalog,holdability,transactionIsolation,readOnly,和typeMap.

ps 设置forceIgnoreUnresolvedTransactionstrue.议员.