代码之家  ›  专栏  ›  技术社区  ›  user674669

启动事务AFTER而不是BEFORE启动单例bean中的同步方法

  •  1
  • user674669  · 技术社区  · 12 年前

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

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

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

    非常感谢。

    更新:我们只是试图拥有一个每次只能由一个线程调用的bean方法。我们不希望任何其他线程调用此方法,直到上一个线程 彻底地 我创建了另一个线程,在那里我得到了使用单例bean的想法: synchronized method in stateless session bean not working as expected in glassfish

    更新:经过阅读,我似乎可以创建自己的事务UserTransaction。这会得到支持吗?不要介意。我收到以下错误消息:

    Only session beans with bean-managed transactions can obtain UserTransaction
    
    2 回复  |  直到 9 年前
        1
  •  1
  •   Gustav Grusell    12 年前

    我认为一种方法是通过将对另一个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中作为额外的保护。

        2
  •  0
  •   win_wave    12 年前

    只需使用 @ConcurrencyManagementType(CONTAINER) 在类级别上,容器将保持同步。使用没有 synchronized 指令。

    推荐文章