Solon v2.7.5

四、事务的全局控制及应用

</> markdown

以下方案只是示例,作为思路拓展。内部不能把异常吃掉否则会失效,且只对 web 项目有效:

1、全局禁掉事务

事务管理默认是开始的。如果不需要,可以:

public class App{
    public static void main(String[] args){
        Solon.start(App.class, args, app->{
            if(app.cfg().isDebugMode()){ //比如在 debug 模式下,关掉事务
                app.enableTransaction(false);
            }
        });
    }
}

2、全局启用事务管理

使用 RouterInterceptor,并放置最内层。启用事务,有异常时会回滚

@Component(index = Integer.MAX_VALUE) //最大值,就是最内层
public class GlobalTranEnabledInterceptor  implements RouterInterceptor {
    @Override
    public void doIntercept(Context ctx, Handler mainHandler, RouterInterceptorChain chain) throws Throwable {
        TranUtils.execute(new TranAnno(), () -> {
            chain.doIntercept(ctx, mainHandler);
        });
    }
}

一般不建议这么干,全局启用事务太浪费性能了。

3、开发调试时回滚一切事务

使用 Filter,并放置最后层。启用事务,并人为造成一个回滚异常(所有事务都会回滚)。

@Component(index = Integer.MIN_VALUE) //最小值,就是最外层
public class GlobalTranRollbackFilter implements Filter {
    @Override
    public void doFilter(Context ctx, FilterChain chain) throws Throwable {
        if (Solon.cfg().isDebugMode()) { //仅有调试模式下有效
            try {
                TranUtils.execute(new TranAnno(), () -> {
                    chain.doFilter(ctx);
                    throw new RollbackException(); //借这个专有异常,人为触发回滚
                });
            } catch (RollbackException e) {
                //略过
            }
        } else {
            chain.doFilter(ctx);
        }
    }

    public static class RollbackException extends RuntimeException {

    }
}