-
1. Re: Executing Outside Transaction
jaikiran Dec 19, 2006 8:00 AM (in response to murtuza52)Try this:
SessionBean2{ @TransactionAttribute(NotSupported) count(){ read counter from database and increase counter }
More details at: http://java.sun.com/j2ee/tutorial/1_3-fcs/doc/Transaction3.html -
2. Re: Executing Outside Transaction
murtuza52 Dec 19, 2006 9:57 AM (in response to murtuza52)I tried your approach, but it does not seems to working in concurrent access to methodA(). Let me explain, I ran test with two threads running almost parallel. Each thread making 100 calls to methodA(). At the end of the test the count should have increased by 200 but its not the case. Its always less than 200. When I looked deeper into the problem I found that two threads calling count() at same time (or before the current thread has written the new counter value to database) will read same counter value from the database. Thus both of them will result in writing same value in the database which is not right. There must be locking mechanism on the table or method which blocks others from access until current thread finishes the count() method. I tried synchronized but in vain.
I appreciate your help and hope to hear better solution from experts.
Murtuza -
3. Re: Executing Outside Transaction
murtuza52 Dec 20, 2006 1:59 AM (in response to murtuza52)I have resolved this problem with @Version attribute. Those who are interested in knowing here is how i did it:
The counter entity bean is modified as follows:@Entity @Table(name = "counter") public class Counter implements Serializable{ private String counterName; private long value; private int version; @Id public String getCounterName() { return counterName; } public void setCounterName(String name) { this.counterName = name; } public long getValue() { return value; } public void setValue(long value) { this.value = value; } @Version public int getVersion() { return version; } public void setVersion(int version) { this.version = version; } }
The update method is modified as follows:public long count(){ Counter counter = manager.find(Counter.class, "methodA"); manager.lock(counter, LockModeType.READ); if(counter==null) { counter = new Counter(); counter.setCounterName(tableName); counter.setValue(1); manager.persist(counter); } long returnValue = counter.getValue(); key.setNextKey(returnValue+1); manager.merge(counter); manager.flush(); return returnValue; }
Murtuza