1

我在 glassfish 中部署了一个战争文件。我们有一个 Singleton bean,其中有 1 个同步方法。

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

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

谢谢你。

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

更新:做了一些阅读之后,似乎我可以创建自己的事务 UserTransaction。会支持吗?没关系。我收到此错误消息:

Only session beans with bean-managed transactions can obtain UserTransaction
4

2 回答 2

1

我认为一种方法是通过将对方法的调用包装在另一个 bean 中来将同步移出 bean(YourBean 将是您的 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 中作为额外的保护措施。

于 2014-08-19T05:11:03.577 回答
0

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

于 2014-08-25T06:59:13.203 回答