Ejb CMT Transaction Attribute NotSupported不会挂起客户端事务

时间:2013-08-13 13:22:22

标签: transactions locking ejb deadlock

我们在EJB 3.0 / JPA 1.0 / DB2 10.1应用程序中遇到表锁定和死锁问题。我们发现,如果在支持事务的ejb方法中简单的SELECT查询被删除,则记录将被锁定(下一个密钥共享锁定 - NS锁定模式),这最终会导致死锁的潜在问题。如果在没有事务的情况下在ejb方法中执行相同的查询,则不会发生锁定,我认为这应该是这样的。

问题:我们有一个需要交易的方法A的ejb ejbA。我们有方法B的ejbB,它具有简单的选择查询,不应该在事务中运行,因此我们将trnasaction属性设置为:NotSupported。我们从methodA调用methodB。

Oracle EE6教程说:如果客户端在事务中运行并调用企业bean的方法,则容器会在调用方法之前挂起客户端的事务。方法完成后,容器将恢复客户端的事务。

正如我们所知,methodB应该挂起来自methodA的事务并且不应该锁定记录,但确实如此,这导致我得出结论:事务没有被暂停。

请帮助我们解决和理解这种行为。

1 个答案:

答案 0 :(得分:0)

你如何致电methodB

如果调用代码如下:

@Stateless
public class MyEJB{

    @TransactionAttribute(REQUIRED)
    public void methodA (){
       ...
       methodB();
       ...
    }

    @TransactionAttribute(NOT_SUPPORTED)
    public void methodB (){
        ...
    }
}

应用程序服务器永远不知道何时挂起事务(方法调用不会调用容器创建的代理方法)。

要正确调用具有不同事务语义的方法,您需要访问SessionContext上可用的增强对象,如下所示:

@Stateless
public class MyEJB{

    @Resource
    SessionContext sc;         

    MyEJB self;  

    @PostConstruct
    public void init(){
      this.self = this.sc.getBusinessObject(MyEJB.class);
    }

    @TransactionAttribute(REQUIRED)
    public void methodA (){
       ...
       self.methodB();
       ...
    }

    @TransactionAttribute(NOT_SUPPORTED)
    public void methodB (){
        ...
    }
}