jfinal 独立事务提交

波总:

有一个需求是这样的,在项目中开启了事务,做了以下操作

A方法:操作数据库

B方法:操作数据库

C方法操作数据库。

参考了您之前提到的 DbKit.getConfig().getConnection().commit();说可以。

所以在B方法中使用了 DbKit.getConfig().getConnection().commit();,然后再C方法报错后,A和B都提交了事务。如果想只要B方法提交事务,A和C都回滚,怎么写呢?


B方法如下:

private Integer add(String name, String code) throws Exception {
    int val=1;
    Connection con = DbKit.getConfig().getThreadLocalConnection();
    PreparedStatement pst = con.prepareStatement("insert into serial(name,code,val) values(?,?,?)");
    pst.setString(1, name);
    pst.setString(2, code);
    pst.setInt(3, val);
    pst.execute();
    con.commit();
    DbKit.getConfig().close(pst,con);
    return val;
}


评论区

JFinal

2020-06-05 23:21

如果 A、B、C 方法都处在同一个线程之中,那么 DbKit.getConfig().getConnection() 得到的 Connection 对象将是共享的,所以无论 A、B、C 哪个方法中 commit() 都将影响其余两个方法

注意看 DbKit.getConfig() 这个方法的实现:
Connection conn = threadLocal.get();
if (conn != null)
return conn;
return showSql ? new SqlReporter(dataSource.getConnection()).getConnection() : dataSource.getConnection();

该方法是优先从 ThreadLocal 中获取 connection 对象,假定你的 A 方法最先调用该方法,后面的 B、C 如果与 A 处在同一个线程,那么获取到的对象与 A 中将是同一个。所以 A、B、C 的事务将融合为一个事务


解决办法自然就简单了:想办法获取独立的 Connection 对象,具体代码如下:
DbKit.getConfig().getDataSource().getConnection()

以上代码将获取到一个全新的 connection 对象,对该对象进行数据库操作,然后进行 commit() 将是它自己独享的

奋斗不止

2020-06-08 08:58

@JFinal 可以了,谢谢波总。

热门反馈

扫码入社