`
yourenyouyu2008
  • 浏览: 287637 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

seam中内嵌的事务回滚拦截器RollbackInterceptor

    博客分类:
  • seam
 
阅读更多

seam中有两种事务管理方式,1)页面请求自动开启、关闭事务,不需要在代码上做任务额外处理;2)通过@Transactional注释在类或方法上增加事务。

第1种是在jsf的PhaseListener(SeamPhaseListener)中实现的,阶段中调用业务方法,阶段后在SeamPhaseListener中根据事务的状态来决定提交还是回滚事务。事务的状态是如何更改的呢?阶段前开始事务后事务的状态是active的,阶段中调用业务方法如果产生异常会改变事务的状态为Rollback,否则事务状态还是active的。由于阶段后不能捕获阶段中的异常,所以通过RollbackInterceptor 拦截器来让业务方法失败后改变事务状态。不是任何异常都会改变事务状态,如下异常才会改变事务状态。

1)所有不带@javax.ejb.ApplicationException或@ApplicationException(seam的)的RuntimeException

2)不包括jsf 的ValidatorException和ConverterException

3)所有带@javax.ejb.ApplicationException或@ApplicationException(seam的),并且rollback=ture的任何Exception

第2种在方法上增加拦截,如果方法本身抛出异常,根据上面的3种异常情况决定是提交还是回滚事务,如果方法捕获了调用其它组件的方法抛出的异常,也可能会导致事务回滚,其它组件的方法中抛出的异常是通过RollbackInterceptor 拦截器来改变事务状态的,这种情况与第1种事务管理方式一样。

//加在每个可拦截的方法上

@Interceptor(stateless=true)
public class RollbackInterceptor extends AbstractInterceptor
{
   private static final long serialVersionUID = 5551801508325093417L;
  
   @AroundInvoke
   public Object aroundInvoke(InvocationContext invocation) throws Exception
   {
      try
      {
         return invocation.proceed();
      }
      catch (Exception e)
      {
         if ( isRollbackRequired(e, getComponent().getType() == JAVA_BEAN) )
         {
            try
            {
               Transaction.instance().setRollbackOnly();//设置当前事务(底层事务)回滚
            }
            catch (Exception te) {} //如果当前线程没有活动的事务,忽略任何异常

         }
         throw e;
      }
   }
  
   public boolean isInterceptorEnabled()
   {
      // Just here for consistency
      return true;
   }
  
}

总结:默认情况下方法中抛出的runtimeException会导致事务回滚,检查时异常不会导致事务回滚,在异常类型不能改变的情况下通过@javax.ejb.ApplicationException或@ApplicationException(seam的)的rollback来决定是否需要回滚事务。

 

如下异常可能就是因为忽略了runtimeException导致的。

2013-01-04 14:50:10,709 ERROR [org.hibernate.util.JDBCExceptionReporter] Transaction is not active: tx=TransactionImple < ac, BasicAction: -53ee3e68:e32b:50e0f672:2d76 status: ActionStatus.ABORT_ONLY >; - nested throwable: (javax.resource.ResourceException: Transaction is not active: tx=TransactionImple < ac, BasicAction: -53ee3e68:e32b:50e0f672:2d76 status: ActionStatus.ABORT_ONLY >)
2013-01-04 14:50:10,709 INFO  [org.hibernate.event.def.DefaultLoadEventListener] Error performing load command
org.hibernate.exception.GenericJDBCException: Cannot open connection
        at org.hibernate.exception.SQLStateConverter.handledNonSpecificException(SQLStateConverter.java:126)
        at org.hibernate.exception.SQLStateConverter.convert(SQLStateConverter.java:114)
        at org.hibernate.exception.JDBCExceptionHelper.convert(JDBCExceptionHelper.java:66)
        at org.hibernate.exception.JDBCExceptionHelper.convert(JDBCExceptionHelper.java:52)
        at org.hibernate.jdbc.ConnectionManager.openConnection(ConnectionManager.java:449)
        at org.hibernate.jdbc.ConnectionManager.getConnection(ConnectionManager.java:167)
        at org.hibernate.jdbc.AbstractBatcher.prepareQueryStatement(AbstractBatcher.java:161)
        at org.hibernate.loader.Loader.prepareQueryStatement(Loader.java:1573)
        at org.hibernate.loader.Loader.doQuery(Loader.java:696)
        at org.hibernate.loader.Loader.doQueryAndInitializeNonLazyCollections(Loader.java:259)
        at org.hibernate.loader.Loader.loadEntity(Loader.java:1881)
        at org.hibernate.loader.entity.AbstractEntityLoader.load(AbstractEntityLoader.java:71)
        at org.hibernate.loader.entity.AbstractEntityLoader.load(AbstractEntityLoader.java:65)
        at org.hibernate.persister.entity.AbstractEntityPersister.load(AbstractEntityPersister.java:3072)
        at org.hibernate.event.def.DefaultLoadEventListener.loadFromDatasource(DefaultLoadEventListener.java:434)
        at org.hibernate.event.def.DefaultLoadEventListener.doLoad(DefaultLoadEventListener.java:415)
        at org.hibernate.event.def.DefaultLoadEventListener.load(DefaultLoadEventListener.java:165)
        at org.hibernate.event.def.DefaultLoadEventListener.proxyOrLoad(DefaultLoadEventListener.java:223)
        at org.hibernate.event.def.DefaultLoadEventListener.onLoad(DefaultLoadEventListener.java:126)
        at org.hibernate.impl.SessionImpl.fireLoad(SessionImpl.java:905)
        at org.hibernate.impl.SessionImpl.get(SessionImpl.java:842)
        at org.hibernate.impl.SessionImpl.get(SessionImpl.java:835)
        at org.hibernate.ejb.AbstractEntityManagerImpl.find(AbstractEntityManagerImpl.java:182)
        at sun.reflect.GeneratedMethodAccessor761.invoke(Unknown Source)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
        at java.lang.reflect.Method.invoke(Method.java:597)
        at org.jboss.seam.persistence.EntityManagerInvocationHandler.invoke(EntityManagerInvocationHandler.java:46)
        at $Proxy174.find(Unknown Source)
        at org.iata.ios.core.dao.BaseDao.find(BaseDao.java:82)
        at org.iata.seurat.app.systemadmin.user.dao.UserDao.getLoginUser(UserDao.java:48)

分享到:
评论
1 楼 nighthawk 2012-12-28  
总结的不错,解决了实际问题

相关推荐

    SEAM 中文开发指南

    ### SEAM 中文开发指南知识点概述 #### 一、SEAM 框架简介 - **SEAM**:SEAM 是一个基于 Java EE 的企业级应用框架,它简化了复杂的应用程序开发过程,并且提供了丰富的功能来支持业务逻辑的实现。 - **版本信息**...

    jboss seam 中文文档集合

    《JSF标签》简体中文版.pdf涵盖了JSF的各种组件、转换器、验证器以及与后台数据交互的方法,有助于提升开发者在JSF项目中的效率。 **4. A4J (Ajax for JSF)** A4J 是一个扩展JSF的库,提供了一套AJAX支持,允许...

    Seam2.0GA 中文开发指南

    `components.xml` 文件是Seam应用的核心配置文件之一,它定义了Seam组件的元数据信息,包括组件的名称、范围、拦截器等。 **1.2.1.5 Web部署描述文件:web.xml** `web.xml` 文件是Web应用的部署描述文件,它定义了...

    JbossSeam中文开发指南.docx

    Seam拦截器是一个基于拦截器的编程模型,能够帮助开发者快速构建企业级应用程序。Seam拦截器提供了一个统一的编程模型,能够将JSF、EJB、JPA等技术整合在一起,提供了一个强大且灵活的开发环境。 Seam异常处理 ...

    seam需要的jar包

    在这个“seam需要的jar包”压缩包中,包含了运行和开发Seam应用程序所需的各种库文件。 首先,Seam框架的核心依赖于JSF,这是Java EE中的一个用户界面组件框架,用于构建交互式Web应用。JSF提供了模型-视图-控制器...

    JBOSS SEAM组件中文手册

    3. **Seam生成器(Seam Generator)**: 提供了一套工具,用于快速生成Seam项目和组件的模板代码,加速开发进程。 4. **测试框架**: Seam 2.0引入了集成测试框架,使得单元测试和集成测试变得更加方便。 5. **国际...

    seam 中文文档 pdf

    seam 中文文档 pdf 格式 JSF+EJB3.0快速开发框架Seam的中文版向导。。。

    jboss seam 中文文档

    - **拦截器**:在 Seam 中,拦截器被用来增强组件的行为,如权限检查、日志记录等。 - **组件名字**:每个 Seam 组件都需要有一个唯一的名称,以便于引用和配置。 - **定义组件作用域**:通过配置文件或注解,可以...

    《SeamInAction》+《JbossSeam》+《官方中文指南》

    此外,Seam还支持CDI,这使得开发者可以利用更多的Java EE特性,如拦截器和异步处理。 总之,拥有《Seam In Action》、《JBoss Seam》和《官方中文指南》这些资源,开发者可以系统地学习和精通Seam框架,从而在企业...

    seam in action 中文 english

    7. **国际化与本地化**:Seam支持多语言环境,对于中英文双语版本的书籍,这为开发者提供了跨越语言障碍的便利,帮助全球的开发者理解和使用Seam框架。 8. **测试支持**:Seam提供了一套完整的测试工具,包括单元...

    seam 框架整合hibernate+jsf

    在JSF动作事件触发时,Seam可以自动开启、提交或回滚事务。 4. **安全性和身份验证**:Seam提供了内置的安全框架,可以轻松集成到JSF应用中,实现用户身份验证和授权。 5. **国际化和本地化**:Seam与JSF结合,...

    seam的注解和标签

    - `@BypassInterceptors`: 如果添加这个注解,那么该方法将绕过拦截器链,这对于性能敏感的操作特别有用。 5. **实战应用** 在实际开发中,Seam注解和标签的结合使用可以极大地简化代码,提高开发效率。例如,...

    jboss seam中文资料

    - **转换器和验证器**:Seam内置了丰富的转换器和验证器,用于处理数据类型转换和输入验证,简化了开发者的工作量。 - **国际化支持**:Seam提供了方便的国际化支持,使得应用能够轻松地适应不同的语言和地区设置。 ...

    JSF项目中seam的配置

    这是Seam启动的基础,监听器会在JSF的生命周期中插入Seam特有的行为,比如对话管理。Seam通过这个监听器能够增强JSF的各个阶段,并引入CONVERSATION生命周期,这是Seam的一个核心特性。 ```xml ...

    seam参考手册中文版

    - **拦截器**: 为组件提供额外的行为扩展点,如日志记录、安全性检查等。 - **组件命名规则**: 为了确保组件名称的唯一性和易于识别,Seam定义了一套规范化的命名机制。 ##### 组件范围定义 - **定义组件作用域**: ...

    jboss seam 学习资料,seam in action和官方手册

    5. **持久化支持**:讨论Seam对JPA和Hibernate的支持,包括实体管理和事务管理。 6. **安全管理**:学习Seam的认证和授权机制,如使用Security子模块。 7. **事件和回调**:了解Seam事件系统的工作方式,以及如何...

    jboss seam 2.0 中文手册

    整理自jboss seam 中文站,压缩为chm格式,便于广大jboss seam爱好者阅读,所有版权归jboss seam中文站所有。

    seam 2中文手册

    seam下一代web开发框架

Global site tag (gtag.js) - Google Analytics