Postgresql setAutoCommit(false)不使用c3p0
我正在使用postgresql 9.2和C3p0 0.9.2.1,我创建了一个连接自定义程序来禁用Postgresql setAutoCommit(false)不使用c3p0,postgresql,jetty,connection-pooling,c3p0,Postgresql,Jetty,Connection Pooling,C3p0,我正在使用postgresql 9.2和C3p0 0.9.2.1,我创建了一个连接自定义程序来禁用autoCommit并设置transactionMode,但是当我在InitialContext上进行查找以检索数据源时,autoCommit不会在连接上被禁用(记录在底部)。如何禁用自动提交 连接自定义程序: public class IsolationLevelConnectionCustomizer extends AbstractConnectionCustomizer {
autoCommit
并设置transactionMode
,但是当我在InitialContext
上进行查找以检索数据源时,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);
}
}
类来检索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.");
}
}
}
日志:
默认情况下,为什么c3p0会自动激活它?我应该将ForceIgnoreUnsolvedTransactions设置为true吗
编辑:每当我在检索数据源后提交事务时,都会出现以下错误:
org.postgresql.util.psqleexception:启用自动提交时无法提交。
状态为“默认值是在创建连接对象时启用自动提交模式”。这是跨DBMS的默认值,与数据库在其他上下文中的行为无关。JDBC程序员可能依赖设置自动提交,除非他们显式调用setAutoCommit(false)
。c3p0对此表示敬意
当未指定单一行为时,c3p0允许ConnectionCustomizer持久覆盖onAcquire()
方法中的连接默认值。例如,规范规定“连接对象的默认事务级别由驱动程序确定
因此,对于transactionIsolation,如果您在Acquire(…)
中重置它,c3p0将记住您选择的默认值,并始终在签出之前将transactionIsolation恢复到默认值。但是,c3p0明确不允许您在Cquire(…)中禁用一次自动提交
,并且默认情况下禁用自动提交
。在签出时,c3p0坚持认为您有符合规范的连接
您可以通过重写onCheckOut(…)
方法来获得所需的行为。当调用onCheckOut(…)
时,连接已经签出,您可以在那里做任何您想做的事情,此时c3p0已经耗尽了它对规范的义务。如果希望客户端始终看到非自动提交连接,请在onCheckOut(…)
中调用setAutoCommit(false)
。但请注意,这会导致客户端代码不可移植。如果您离开c3p0并切换到另一个数据源,您将需要使用一些其他特定于库的方法来始终禁用自动提交
,否则您将发现您的应用程序行为不正常。因为即使对于postgres,JDBC连接在默认情况下也是autoCommit
注意:其值不由规范固定,因此可以在onAcquire(…)
方法中持久覆盖的连接属性有目录
,可保持性
,事务处理
,只读
,以及类型映射
p、 s.不要将
forceignoreunsolvedtransactions
设置为true
。谢谢你的回答!我认为在创建连接时,它会触发onAcquire()
,并且一旦连接必须返回池,就会触发onCheckOut()
。因此,我会在onAcquire()
或onCheckIn()中禁用autoCommit
。我将尝试在池从数据库获取连接后立即调用oncheckoutonaquire()时执行此操作,并且不涉及特定的客户端。当客户端在逻辑上将连接从池中签出后,在客户端看到连接之前签出连接时,调用onCheckOut()。onCheckIn()是在客户端close()关闭连接之后,在连接逻辑签入池之前调用的。onDestroy()是在物理连接破坏之前调用的。
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