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

16 篇文章 0 订阅
15 篇文章 0 订阅

服务端后台管理这种如果代码中抛出异常,其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 support
			try {
				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
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值