Tx concurrency Bug in weblogic 10?

Look at the code ...

When the Timer service calls my execute() method, it will start a new transaction with createDepartment().

Then, I get this exception:
thread already associated with another transaction


Note there is 2 timers that will call execute at the same time....
When I try it with a single timer it works fine. So I guess, there is a concurrency problem here!!

I'm I missing something or its a bug in Weblogic??


import java.util.Date;
 
import javax.annotation.Resource;
import javax.ejb.EJB;
import javax.ejb.SessionContext;
import javax.ejb.Stateless;
import javax.ejb.Timeout;
import javax.ejb.Timer;
import javax.ejb.TimerService;
import javax.ejb.TransactionAttribute;
import javax.ejb.TransactionAttributeType;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
 
 
@Stateless
public class testSession implements testSessionLocal {
 
	
	@EJB
	private testSessionLocal sessionLocal;
	
	@Resource
	private SessionContext ctx;
	
	@PersistenceContext(name="TESTTX_PERSISTENCE_CTX")
	private EntityManager entityManager;
	
	
	public void start(){
		
		TimerService service = ctx.getTimerService();
		service.createTimer(new Date(), 1000, null);
		service.createTimer(new Date(), 1000, null);
	}
	
	@Timeout
	public void execute(Timer timer){
		
		sessionLocal.createDepartment();
	}
	
	
	@TransactionAttribute(TransactionAttributeType.REQUIRES_NEW)
	public void createDepartment(){
		
		Department dep = new Department();
		dep.setName("My Department");
		
		entityManager.persist(dep);
	}
	
}

Open in new window

kmapperAsked:
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

Mr_ItCommented:
It seems that it's a weblogic bug. I tried your code in JBoss 5 and there it works.

In the EJB specs you can read:

4.7.11 Non-reentrant Instances
The container must ensure that only one thread can be executing an instance at any time... yada yada ...

Try to figure out if the two timers are attempting to invoke the same session object at once.  When this is the case, it is certainly a bug.

By the way, it's a bit strange to see you inject a session bean of the same class in the session bean.  The code snippet below should work as well.

Remark 1: If you don't really need the createDepartment method in your local business interface, you could write its contents directly in the timer method itself as well. That will make your code even shorter.

@Stateless
public class testSession implements testSessionLocal {
       
        @Resource
        private SessionContext ctx;
        
        @PersistenceContext(name="TESTTX_PERSISTENCE_CTX")
        private EntityManager entityManager;
        
        public void start(){
                TimerService service = ctx.getTimerService();
                service.createTimer(new Date(), 1000, null);
                service.createTimer(new Date(), 1000, null);
        }
        
        @Timeout
        @TransactionAttribute(TransactionAttributeType.REQUIRES_NEW)
        public void execute(Timer timer){
                createDepartment(); // Will NOT start a new transaction
        }
        
        
        @TransactionAttribute(TransactionAttributeType.REQUIRES_NEW)
        public void createDepartment(){
                
                Department dep = new Department();
                dep.setName("My Department");
                
                entityManager.persist(dep);
        }
        
}

Open in new window

0

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
kmapperAuthor Commented:
Thank you for that answer. We also tried it in JBoss 5 yesterday and ended to the same conclusion.


"By the way, it's a bit strange to see you inject a session bean of the same class in the session bean.  The code snippet below should work as well. " 

We just did that for test purposes. But sometimes we use this to create new transactions within our bean. Like for a bean that would, let's say, fetch all files in a folder and do some processing on all of them, then we inject a session bean in our bean to call the ProcessFile() method which has a REQUIRES_NEW TransactionAttribute to isolate each file processing.

Do you know any better way to achieve this result. And as far as you know, is this prohibited? Thank you!
0
Mr_ItCommented:
In my code, the container will start a new transaction around the  timeout callback method itself. But note that the EJB specs state:

'For an enterprise beans timeout callback method only the REQUIRES, REQUIRES_NEW and
NOT_SUPPORTED transaction attributes may be used.'

If that does not suits your needs (you need to call multiple business methods in different transactions), you must invoke the business method through an injected bean, so that the container can manage the transactions.
0
kmapperAuthor Commented:
Thank you
0
Mr_ItCommented:
Thanks :-p
0
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
Java App Servers

From novice to tech pro — start learning today.

Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.