Java EE @TransactionManagement.BEAN——它如何与容器管理的BEAN结合



在以下场景中,在callSessionBean2()中启动的事务将如何表现?它暂停了吗?如果在SessionBean2中抛出异常会发生什么?SessionBean2设置为BEAN事务管理类型,因为它不与任何数据库通信,仅通过LDAP与AD服务器通信。

我问,因为我一直有问题在生产服务器部署后的几个星期,调用SessionBean2开始挂起,事务超时作为唯一的错误。我觉得这种设置可能是件坏事,有人能解释一下吗?

@Stateless
@TransactionManagement(TransactionManagementType.CONTAINER)
public class SessionBean1 {
    @Inject private SessionBean2 sessionBean2;
    @TransactionAttribute(TransactionAttributeType.REQUIRED)
    public void callSessionBean2(){
        sessionBean2.doThingsThatMightCauseException();
    }
}
@Singleton
@TransactionManagement(TransactionManagementType.BEAN)
public class SessionBean2 {
    public void doThingsThatMightCauseException(){...}
}

在EJB 3.1规范(§13.6.1)中声明,调用者的事务将被挂起:

如果客户端请求与事务T1相关联,则实例未与事务关联时,容器将挂起对象调用该方法未指定的事务上下文。容器恢复客户机的事务关联(T1)当方法(与任何关联的拦截器方法)完成。

因此,与SessionBean1相关联的事务被挂起,并且SessionBean2在任何情况下抛出的异常将由调用bean处理,使用适当的语义(即由CMT会话处理)

你的代码是正确的,尽管我宁愿使用:

@TransactionManagement(TransactionManagementType.CONTAINER)
@TransactionAttribute(TransactionAttributeType.NOT_SUPPORTED)
public class SessionBean2 {
    public void doThingsThatMightCauseException(){...}
}

有同样的效果

您遇到的问题可能与@Singleton注释有关根据§4.8.5.3和§4.8.5.3,默认bean为:

@ConcurrencyManagement(ConcurrencyManagementType.CONTAINER)
@Lock(LockType.WRITE)

这会序列化doThingsThatMightCauseException的调用,导致随机的ConcurrentAccessTimeoutException。虽然可以通过@AccessTimeout配置并发访问超时,但如果(序列化的)doThingsThatMightCauseException访问延迟超过为CMT事务定义的超时,则会导致事务超时(请记住,与SessionBean1关联的CMT事务被挂起,但时钟仍在计数……)。

结束:

你需要改变doThingsThatMightCauseException上的访问锁(要注意共享状态):

@Lock(LockType.READ)
public void doThingsThatMightCauseException(){...}

这将删除访问序列化,有望解决超时问题。

如果仍然遇到超时,则与doThingsThatMightCauseException中包含的操作缓慢有关。在这种情况下,您需要:

  • 在任何事务之外调用方法,
  • 或更改CMT事务超时(在特定于AS的配置/部署中)
  • 或将SessionBean1转换为BMT,从而利用UserTransaction.setTransactionTimeout

我的建议是手动管理所有事务。根据Java 6 EE规范:

使用容器管理事务划分的企业bean不能使用任何干扰事务管理的方法容器的事务划分边界。这类例子的commit、setAutoCommit和rollback方法的提交和回滚方法javax.jms.Session。如果你需要控制交易划分,必须使用应用程序管理的事务划分。

使用容器管理事务划分的企业bean也不能使用javax.transaction.UserTransaction接口。

相关内容

  • 没有找到相关文章

最新更新