start transaction AFTER not BEFORE同步方法在单例bean中开始



我在glassfish中部署了一个war文件。我们有一个单例bean,其中有一个同步方法。

@TransactionAttribute (TransactionAttributeType.REQUIRED)
public synchronized void do()
{
    ...
}

然而,我注意到事务是在调用方法之前启动的。在调用者获得bean类监视器上的锁之后,如何启动事务?

谢谢。

更新:我们只是想有一个bean方法,一次只能由一个线程调用。在前一个线程完全完成之前,我们不希望任何其他线程调用该方法。我创建了另一个线程,在那里我得到了使用单例bean的想法:无状态会话bean中的同步方法在glassfish

中不像预期的那样工作

更新:在做了一些阅读之后,似乎我可以创建我自己的事务UserTransaction。会得到支持吗?不要紧。我得到了这个错误信息:

Only session beans with bean-managed transactions can obtain UserTransaction

我认为一种方法是通过将对方法的调用包装在另一个bean (YourBean将是您的bean类的接口)中来将同步移出bean:

public class WrapperBeanImpl implements WrapperBean {
  private YourBean yb;
  private final Object lock;
  @Resource
  private SessionContext ctx;
  @PostConstruct
  public void init() {
    yb = ctx.getBusinessObject(YourBean.class);
  }
  @TransactionAttribute(TransactionAttributeType.NEVER)
  public void synchronizedDo() {
    synchronized(lock) {
      yb.do();
    }
  } 
}

(从http://www.javahelp.info/2009/11/01/using-transactionattribute-in-submethods-on-same-ejb3-beans/略微修改的示例)

当然,这并不能真正阻止任何人直接调用do()方法,绕过这个额外的同步,尽管这可能不是问题。您还可以选择在bean中保留同步,作为额外的保护措施。

只要在类级别上使用@ConcurrencyManagementType(CONTAINER),容器将保持同步。并且使用没有synchronized指令的方法

最新更新