Hello. I'm trying to build an scenario with the following behaviour:
Two kind of messages can be feeded into a JMS queue:
-NEW. Messages that triggers the creation of a new entity (ejb3.test.AEntity).
-INCR. Messages that triggers the modification of a persistent property
of a given entity(ejb3.test.AEntity).
ejb3.test.AEntity is a simple versioned entity with just a persistent property
(other than version and id) called counter. It exposes a bussiness method to
increment that counter as:
public void incr() {
logger.info("incr called for " + this);
setCounter( getCounter() + 1);
}
I have a MDB to handle the messages. NEW messages are handled in the following
fashion:
Creates a new AEntity instance.
Persist it in the injected EntityManager.
Flushes the Entity Manager.
Send 10 INCR messages.
INCR messages are handled as:
Finds the AEntity that the message is referenced to (using a property into
the message).
Locks the AEntity.
Calls the AEntity bussiness method: incr().
This scenario does not work using Oracle as DataSource: The AEntity is created,
but the MDBs handling the 'INCR' messages are not able to find that Entity
using:
AEntity a = manager.find(AEntity.class, aId);
I suppose that the problem is that the transaction for the MDB handling the
'NEW' message has not finished. But, shouldn't the EntityManager.flush() commit
the changes to the DataBase? I tried to change the MDB to BMT and it worked in
that way.
On the other hand, this worked under Hypersonic, supposedly because it only
implements UNCOMMITED_READ as isolation transaction level. Also, I got warning
with Hypersonic trying to use:
manager.lock(a, LockModeType.READ);
in my attempts to lock the AEntity instance before calling its business method:
AEntity a = manager.find(AEntity.class, aId);
if ( a != null ) {
manager.lock(a, LockModeType.READ);
a.incr();
} else {
logger.warn("No entity with id " + aId);
}
Unfortunately, using Oracle 9i as DataSource, the INCR handlers are never able
to see the Entity (manager.find returns null). With Hypersonic, the entity
becomes available after flushing the EntityManager (READ_UNCOMMITED).
Furthermore, when using an UserTransaction with BMT, the Entity is visible by
the 'INCR' MDB handlers but they seems to see the entity in a concurrent
fashion, hence, the final result of the counter field is not valid.
Also, trying to use manager.lock(a, LockModeType.WRITE) with a previously
created Entity, using CMT, finishes in a NullPointerException:
2006-07-28 13:37:03,801 ERROR [ejb3.test.MsgHandler] Errors found:
java.lang.NullPointerException at
org.hibernate.persister.entity.AbstractEntityPersister.lock(AbstractEntityPersister.java:1282)
at
org.hibernate.event.def.AbstractLockUpgradeEventListener.upgradeLock(AbstractLockUpgradeEventListener.java:88)
at
org.hibernate.event.def.DefaultLockEventListener.onLock(DefaultLockEventListener.java:64)
at org.hibernate.impl.SessionImpl.fireLock(SessionImpl.java:586)
at org.hibernate.impl.SessionImpl.lock(SessionImpl.java:578)
at
org.hibernate.ejb.AbstractEntityManagerImpl.lock(AbstractEntityManagerImpl.java:337)
at
org.jboss.ejb3.entity.TransactionScopedEntityManager.lock(TransactionScopedEntityManager.java:101)
After reading the EJB3 Persistence specification, I think that using
EntityMager.lock() should avoid the concurrent MDBs trying to get the Entity to
access it, and the transactions implied should be serialized to avoid
inconsistencies (physically locking the DB row related with the entity). I'm a
newbie in this ejb3 world (even in j2ee world) so, I would like to know if I
have make any (or a lot of ) mistake in my assumptions or code.
Best regards.
View the original post :
http://www.jboss.com/index.html?module=bb&op=viewtopic&p=3961545#3961545
Reply to the post :
http://www.jboss.com/index.html?module=bb&op=posting&mode=reply&p=3961545
_______________________________________________
jboss-user mailing list
[email protected]
https://lists.jboss.org/mailman/listinfo/jboss-user