Struts2 OSIV模式下的异常处理及事务回滚解决方案

Struts2与Hibernate整合,有时会使用OpenSessionInView模式控制会话及事务,那么这时Filter的设计通常如下:

try {

打开会话;

获取事务;

chain.doFilter();

事务提交;

} catch (Exception e) {

事务回滚;

}

看似很合理,但是catch里面的语句块无法到达,即使过程中出现异常,也无法到达,原因就是事务被Struts2的拦截器捕获了,没有继续向上抛,所以这时,想通常Filter控制事务回滚,看似不太可能了,没关系,我们换个思路.....

我们可以通过interceptor来实现这个功能,即自定义一个interceptor,伪代码如下:

try {

invacation.invoke();

} catch (Exception e) {

Session session = 通过ThreadLocal获得Session;

Transaction tx = session.getTransaction();

tx.rollback();

}

之后在struts.xml中配置intercepter-stack,这里需要注意这个interceptor必须放在default-stack的下面,即interceptor-stack的最下面:

<interceptor-stack>

<interceptor-ref name="default-stack"/>

<interceptor-ref name="rollback"/>

</interceptor-stack>

然后将默认的interceptor-stack声明成这个,那么相应的Filter里面就需要改成如下形式:

doFilter() {

获取会话;

获取事务;

chain.doFilter();

if(事务没回滚) {

提交事务;

}

}

这样便可以在发现异常的时候,让事务回滚了,前提,这里的Session是利用ThreadLocal做好的线程范围的Session,这样获取Session的时候才可以保证获得的是同一个Session,但是好像现在的最新版本Hibernate已经内置了ThreadLoad的处理了,不需要我们自己来写了。

如果大家有什么更好的方法,欢迎交流。


你可能感兴趣的:(Hibernate,exception,session,struts,Interceptor,filter)