开发者社区> 问答> 正文

关于JFinal事务回滚的几个问题?报错

最近迷上JFinal,想在手上的项目中使用,无奈在事务方面遇到一些问题,还请各路高手指教。(我用的是传说中加了特效的JFinal 2.0)

问题一:在使用声明式事务(@Before(Tx.class))的情况下,如何对事务进行手动回滚。比如:

public class LoanLiabilityController extends Controller {
    public void reg() {
        LoanLiability ll = new LoanLiability();
        String jo = ll.reg();
        renderJson(jo);
    }
}

public class LoanLiability extends Model<LoanLiability>{
    @Before(Tx.class)
    public String reg() {
        Db.update(...);
        int n = Db.update(...);
        if (n == 0) {
            //这里要回滚
        } else {
            Db.update(...);
        }
        return "success";
    }
}

目前我能想到的是在需要回滚的地方throw new NestedTransactionHelpException()来触发Tx的回滚操作,但貌似这会直接跳过Controller中后面的代码,导致ajax收不到返回的内容。另外一种方法,在需要回滚的地方用DbKit.getConfig().getThreadLocalConnection().rollback();,但这样会导致无法在嵌套事务的情况下无法通知外层事务进行回滚。请问是否有高招能够解决这个问题?

问题二:JFinal 2.0中,@Before()是否已经支持在业务层使用?使用前是否需要用Duang.duang()加特效?

问题三:加特效用的Duang.duang()函数是否仅支持无参数的构造函数?例如,我用Duang.duang(new A(123))时,会报错Superclass has no null constructors but no arguments were given。

展开
收起
爱吃鱼的程序员 2020-06-12 14:08:18 726 0
1 条回答
写回答
取消 提交回答
  • https://developer.aliyun.com/profile/5yerqm5bn5yqg?spm=a2c6h.12873639.0.0.6eae304abcjaIB

       问题一:不建议手动回滚。对于@Before(Tx.class)只要抛出异常便可回滚事务,对于Db.tx(...)只要返回false或者抛出异常便可回滚事务。如果需要处理抛出的异常,可以在业务层加特效,并且在控制层trycatch进行分支处理。

       问题二:Before支持在任意层使用,唯一的不同是:在控制层的时候拦截的触发是自动的,在其它层需要先Duang.duang(..)一下才会触发,这个在手册有明确说明。

       问题三:加特效用的Duang.duang(...)与Enhancer.enahce(...)支持带参构造函数,出现异常与jfinal无关,因为出现这个异常时你可以使用newA(123)进行验证,异常仍然会出来。

       最后,如果希望在事务抛出异常后能有更加精细化的处理,除了在控制层对加了事务特效的业务层使用trycatch以外,还可以使用全局拦截器对这类异常进行统一处理。

    嗯,好的,我想通了。就是出现需要回滚的情况就直接抛异常出来,如果中间需要做特殊处理,就用trycatch拦下来,否则,直接抛到全局拦截器里去。明白了,谢谢波总指点~

    1.如果你要在controller使用事物,可以直接用全局拦截器或者@Before(Tx.class)

    2.如果要在service层或者model中使用@Before(Tx.class), 要Enhancer(或者duang)来增强类实例

    LoanLiabilityll= Enhancer.enhance(LoanLiability.class);

    LoanLiabilityServicellService=  Enhancer.enhance( LoanLiabilityService.class);

    3. ajax收不到返回的内容,应该是你没有处理全局异常,最好使用一个拦截器,然后trycatch拦截器中invoke方法,捕获所有的异常做异常提示页面

    前2点清楚了,谢谢。关于第3点,添加拦截器只能解决执行不到renderJson的问题,但是在renderJson之前reg之后完全可能存在别的逻辑,这部分逻辑应该保留在Controller中处理,而不适合上升到拦截器中去处理的,这样子还是无法解决回滚之后Controller后续逻辑无法执行到的问题。手动回滚 还没用过 不过多表操作事问题 也挺奇葩的。
    2020-06-12 14:08:34
    赞同 展开评论 打赏
问答分类:
问答标签:
问答地址:
问答排行榜
最热
最新

相关电子书

更多
低代码开发师(初级)实战教程 立即下载
冬季实战营第三期:MySQL数据库进阶实战 立即下载
阿里巴巴DevOps 最佳实践手册 立即下载