我们在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的事务并且不应该锁定记录,但确实如此,这导致我得出结论:事务没有被暂停。
请帮助我们解决和理解这种行为。
答案 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 (){
...
}
}