javajakarta-eeglassfishstateless-session-beansession-bean

start transaction AFTER not BEFORE start of synchronized method in singleton bean


I have a war file deployed in glassfish. We have a Singleton bean and we have 1 synchronized method in it.

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

However, I am noticing that transaction is started before the method is called. How do I start a transaction after the caller obtains the lock on the bean class' monitor?

Thank you.

Update: We are just trying to have a bean method that can only be called by one thread at a time. We do not want any other thread to call this method until the previous thread is completely done with it. I had created another thread where I got the idea of using a singleton bean: synchronized method in stateless session bean not working as expected in glassfish

Update: After doing some reading, it seems I can create my own transactions UserTransaction. Will that be supported? Never mind. I got this error message:

Only session beans with bean-managed transactions can obtain UserTransaction

Solution

  • I think one way would be to move the synchronization out of the bean by wrapping the call to the method inside another bean (YourBean would be the interface of your bean class):

    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();
        }
      } 
    }
    

    (Example slightly modified from http://www.javahelp.info/2009/11/01/using-transactionattribute-in-submethods-on-same-ejb3-beans/ )

    Of course, this does not really stop anyone from calling the do() method directly bypassing this extra synchronization, although that may not be a problem. You also have the option of leaving the synchronization in your bean as an extra safeguard.