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

来源:互联网 发布:彩票预测app源码 编辑:程序博客网 时间:2024/04/28 22:02

最近开发时使用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);


0 0
原创粉丝点击