Still celebrating National IT Professionals Day with 3 months of free Premium Membership. Use Code ITDAY17

x
?
Solved

Tx concurrency Bug in weblogic 10?

Posted on 2008-10-23
5
Medium Priority
?
609 Views
Last Modified: 2013-12-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

0
Comment
Question by:kmapper
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 3
  • 2
5 Comments
 
LVL 4

Accepted Solution

by:
Mr_It earned 2000 total points
ID: 22794228
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
 

Author Comment

by:kmapper
ID: 22796110
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
 
LVL 4

Assisted Solution

by:Mr_It
Mr_It earned 2000 total points
ID: 22810947
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
 

Author Closing Comment

by:kmapper
ID: 31509195
Thank you
0
 
LVL 4

Expert Comment

by:Mr_It
ID: 22812950
Thanks :-p
0

Featured Post

Will your db performance match your db growth?

In Percona’s white paper “Performance at Scale: Keeping Your Database on Its Toes,” we take a high-level approach to what you need to think about when planning for database scalability.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Verbose logging is used to diagnose garbage collector problems. By default, -verbose:gc output is written to either native_stderr.log or native_stdout.log.   It is also possible to redirect the logs to a user-specified file. This article will de…
Most of the developers using Tomcat find it easy to configure the datasource in Server.xml and use the JNDI name in the code to get the connection.  So the default connection pool using DBCP (or any other framework) is made available and the life go…
The viewer will learn how to implement Singleton Design Pattern in Java.
This tutorial covers a practical example of lazy loading technique and early loading technique in a Singleton Design Pattern.

704 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question