客户端和服务端对异常的不同处理态度【JFinal】

来源:互联网 发布:淘宝店推广方式 编辑:程序博客网 时间:2024/06/15 01:07

服务端后台管理这种如果代码中抛出异常,其Tx事务能起作用,但是在客户端与服务端交互的时候很多都是通过JSON或者XML格式,为了用户体验,成功的话就正常返回,不成功也应该给出失败的信息,而不是直接报505这种错误,那么我们就需要在服务端自己处理掉异常,这样Tx就认为你的代码自己能处理异常,它就不起作用了。我回去查看了Tx的源码,它的原理就是在操作之前设置非自动提交,然后捕获异常,有异常就回滚,没有异常就提交。我们在写的时候也可以参照它的实现,相当于将我们处理的异常和数据库的处理异常合并。【基于JFinal】!!在这个Tx的源码中,当他抓到RuntimeException,它就继续把这个异常往外抛,否者就抛出ActiveRecordException(t),所以我们如果在我们的源码中应用了Tx,我们应该应用下面经过改造的Tx--》TxDoneEx,异常合并处理,而不要往外抛,是controller方法中还是可以自己处理异常,然后还需要往外抛,以TxDoneEx 能回滚事务。

将下面的所有处理异常的地方都改为我们自己处理,而不是往外抛。

public class TxDoneEx implements Interceptor {public static Config getConfigWithTxConfig(Invocation inv) {TxConfig txConfig = inv.getMethod().getAnnotation(TxConfig.class);if (txConfig == null)txConfig = inv.getTarget().getClass().getAnnotation(TxConfig.class);if (txConfig != null) {Config config = DbKit.getConfig(txConfig.value());if (config == null)throw new RuntimeException("Config not found with TxConfig: " + txConfig.value());return config;}return null;}protected int getTransactionLevel(Config config) {return config.getTransactionLevel();}public void intercept(Invocation inv) {Config config = getConfigWithTxConfig(inv);if (config == null)config = DbKit.getConfig();Connection conn = config.getThreadLocalConnection();if (conn != null) {// Nested transaction supporttry {if (conn.getTransactionIsolation() < getTransactionLevel(config))conn.setTransactionIsolation(getTransactionLevel(config));inv.invoke();return ;} catch (SQLException e) {throw new ActiveRecordException(e);}}Boolean autoCommit = null;try {conn = config.getConnection();autoCommit = conn.getAutoCommit();config.setThreadLocalConnection(conn);conn.setTransactionIsolation(getTransactionLevel(config));// conn.setTransactionIsolation(transactionLevel);conn.setAutoCommit(false);inv.invoke();conn.commit();} catch (NestedTransactionHelpException e) {if (conn != null) try {conn.rollback();} catch (Exception e1) {e1.printStackTrace();}} catch (Throwable t) {if (conn != null) try {conn.rollback();} catch (Exception e1) {e1.printStackTrace();}throw t instanceof RuntimeException ? (RuntimeException)t : new ActiveRecordException(t);}finally {try {if (conn != null) {if (autoCommit != null)conn.setAutoCommit(autoCommit);conn.close();}} catch (Throwable t) {t.printStackTrace();// can not throw exception here, otherwise the more important exception in previous catch block can not be thrown}finally {config.removeThreadLocalConnection();// prevent memory leak}}}}

后来询问JFinal的作者詹波,得到了更好的解决方案。

无论如何返回给客户端一个json串http://www.oschina.net/question/2686150_2184260,它其中的一种方法Db.tx就是我这种解决方案


0 0
原创粉丝点击