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

AntonioChen 发布于 2015/09/03 17:35
阅读 1K+
收藏 1

最近迷上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。

加载中
1
JFinal
JFinal

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

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

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

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

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

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

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

LoanLiability ll = Enhancer.enhance(LoanLiability.class);

LoanLiabilityService llService = Enhancer.enhance(LoanLiabilityService.class);

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

AntonioChen
AntonioChen
前2点清楚了,谢谢。 关于第3点,添加拦截器只能解决执行不到renderJson的问题,但是在renderJson之前reg之后完全可能存在别的逻辑,这部分逻辑应该保留在Controller中处理,而不适合上升到拦截器中去处理的,这样子还是无法解决回滚之后Controller后续逻辑无法执行到的问题。
0
weir2008
weir2008
手动回滚   还没用过  不过 多表操作事问题  也挺奇葩的。
返回顶部
顶部