詹总,你好,我用jfinal做的我们单位的一个项目运行了很久了,现在想问你连个问题:
我这个项目有个后台对账服务,是用定时任务运行的,因为过程比较多用到了事物,并且我需要在子程序报错的时候把报错的业务信息抛出去,可以捕获异常的信息(这个事务中那个业务步骤报错,报的什么错误信息),jfinal本身的事务Db.tx的方式方便是方便,但是只能单纯的回退事务但是不能向上抛出异常的信息。这个现在最新的3.6有可行的解决方式吗。
我目前采用的方式是找的网上一个人解决方式:
public static void beginTran() { try { log.info("~~~~~~~~~~~~开启事务~~~~~~~~~~~~"); DbKit.getConfig().setThreadLocalConnection(DbKit.getConfig().getConnection()); DbKit.getConfig().getThreadLocalConnection().setAutoCommit(false); } catch (Exception e) { throw (new RuntimeException(e)); } } public static void commit() throws RuntimeException{ try { log.info("~~~~~~~~~~~~结束事务:提交~~~~~~~~~~~~"); DbKit.getConfig().getThreadLocalConnection().commit(); DbKit.getConfig().getThreadLocalConnection().setAutoCommit(true); DbKit.getConfig().close(DbKit.getConfig().getThreadLocalConnection()); DbKit.getConfig().setThreadLocalConnection(null); } catch (Exception e) { throw (new RuntimeException(e)); } } public static void rollback(){ try { log.info("~~~~~~~~~~~~结束事务:回滚~~~~~~~~~~~~"); DbKit.getConfig().getThreadLocalConnection().rollback(); DbKit.getConfig().getThreadLocalConnection().setAutoCommit(true); DbKit.getConfig().close(DbKit.getConfig().getThreadLocalConnection()); DbKit.getConfig().setThreadLocalConnection(null); } catch (Exception e) { throw (new RuntimeException(e)); } }
调用的时候
try{ JFinalTX.beginTran(); cmerBatch=service.getSettleData(cmerBatch); checkChnlSettle(cmerBatch); JFinalTX.commit(); }catch (BusiException e) { log.error("[{}][{}]对账发生错误",cmer.getCmerId(),cmerBatch.getBatchDate()); JFinalTX.rollback(); cmerBatch.setSttlAbs(e.getErrMsg()); cmerBatch.setSttlStatus(CmerSttlStatus.错误.getCode()); cmerBatch.setSttlDatetime(CMB.getCurrentDateTimeFull()); e.printStackTrace(); throw e; }catch (Exception e) { JFinalTX.rollback(); log.error("[{}][{}]对账发生错误",cmer.getCmerId(),cmerBatch.getBatchDate()); e.printStackTrace(); cmerBatch.setSttlAbs(e.getMessage()); cmerBatch.setSttlStatus(CmerSttlStatus.错误.getCode()); cmerBatch.setSttlDatetime(CMB.getCurrentDateTimeFull()); throw new BusiException(e.getMessage()); }finally{ cmerBatch.update(); }
这种方式 开发测试时挺好用的,但是实际运营中经常出现卡死的现象,就是日志显示运行在代码开始的地方,然后就不动了,然后定时任务一次一次的触发,都卡到任务开始的地方 了,重启tomcat立马就好了。
是在找不到是什么原因,感觉是和数据库连接池有关,用的阿里的Druid,因为是对账,把批量插入放在了事务里,但数量级不多几k而已,好像和异常有关,出现异常后会更容易出现卡死现象。
项目:JFinal
其实 Db.tx 已经很好支持你们的用法,Db.tx 本身就是先回滚事务,然后该抛什么异常就抛什么异常:
try {
Db.tx( () -> {
这里是业务代码
});
} catch (Exception e1) {
Exception e2 = e.getCause(); // 得到更内部的异常
}