c3p0连接池事务不能回滚的问题

最近开发时使用c3p0连接池,数据库用的mysql的InnoDB,但是发现事务提交出错之后不能回滚。查了多方原因,查看mysql的log时发现rollback命令也执行了,但是在事务执行开始的时候并没有去SET autocommit=0的操作。更换了数据库连接池,并且把setAutocommit=false,这个时候发现问题不在。那就之能是c3p0的问题了。

但是c3p0并没有setAutocommit=false这个属性配置。

此时需要配置一个ConnectionCustomizer

public class YourConnectionCustomizer extends AbstractConnectionCustomizer{


    public void onCheckOut( Connection c, String parentDataSourceIdentityToken  ) throws Exception
    {
        super.onCheckOut(c, parentDataSourceIdentityToken);
        System.out.println("手动关闭自动提交");
        c.setAutoCommit(false);
    }
}
并且修改c3p0配置文件

    <property name="connectionCustomizerClassName" value="cn.vodone.base.database.c3p0.IsolationLevelConnectionCustomizer"/>


这个时候会发现,在事务执行之前有SET autocommit=0了

事务回滚成功。

关于connectionCustomizerClassName

connectionCustomizerClassName
default : null
用来定制Connection的管理,比如在Connection acquire 的时候设定Connection的隔离级别,或者在
Connection丢弃的时候进行资源关闭,就可以通过继承一个AbstractConnectionCustomizer来实现相关
方法,配置的时候使用全类名。有点类似监听器的作用。

关于接口描述:

/**
 *  <p>Implementations of this interface should
 *  be immutable, and should offer public,
 *  no argument constructors.</p>
 *
 *  <p>The methods are handed raw, physical
 *  database Connections, not c3p0-generated
 *  proxies.</p>
 *
 *  <p>Although c3p0 will ensure this with
 *  respect to state controlled by
 *  standard JDBC methods, any modifications
 *  of vendor-specific state shold be made
 *  consistently so that all Connections
 *  in the pool are interchangable.</p>
 */
public interface ConnectionCustomizer
{
    /**
     *  <p>Called immediately after a 
     *  Connection is acquired from the
     *  underlying database for 
     *  incorporation into the pool.</p>
     *
     *  <p>This method is only called once
     *  per Connection. If standard JDBC
     *  Connection properties are modified
     *  [holdability, transactionIsolation,
     *  readOnly], those modifications
     *  will override defaults throughout
     *  the Connection's tenure in the
     *  pool.</p>
     */
    public void onAcquire( Connection c, String parentDataSourceIdentityToken )
	throws Exception;

    /**
     *  Called immediately before a 
     *  Connection is destroyed after
     *  being removed from the pool.
     */
    public void onDestroy( Connection c, String parentDataSourceIdentityToken )
	throws Exception;

    /**
     *  Called immediately before a 
     *  Connection is made available to
     *  a client upon checkout.
     */
    public void onCheckOut( Connection c, String parentDataSourceIdentityToken )
	throws Exception;

    /**
     *  Called immediately after a 
     *  Connection is checked in,
     *  prior to reincorporation
     *  into the pool.
     */
    public void onCheckIn( Connection c, String parentDataSourceIdentityToken )
	throws Exception;
}

由此可见,在从连接池中拿connection的时候,会触发onCeckout方法,所以需要手动setAutoCommit(false);


  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值