Solved

Tx concurrency Bug in weblogic 10?

Posted on 2008-10-23
5
603 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 500 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 500 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

Manage your data center from practically anywhere

The KN8164V features HD resolution of 1920 x 1200, FIPS 140-2 with level 1 security standards and virtual media transmissions at twice the speed. Built for reliability, the KN series provides local console and remote over IP access, ensuring 24/7 availability to all servers.

Question has a verified solution.

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

Suggested Solutions

Title # Comments Views Activity
bitbucket vs gitbucket 3 132
printing a file in reverse order is easy in recursion rather than in iteration 3 76
web application structure 18 135
hashmap order 17 63
I had a project requirement for a displaying a user workbench .This workbench would consist multiple data grids .In each grid the user will be able to see a large number of data. These data grids should allow the user to 1. Sort 2. Export the …
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…
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.
Suggested Courses

739 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