Container managed transactions in JBoss AS 5.0
objectswitch Dec 5, 2008 5:44 PMJust downloaded the newly released AS 5.0.0 GA with the Naga PojoCache.
I tried to use a @Replicable object in a session bean using CMT, but for some reason the cache isn't honoring the transaction. For comparison, I also manipulated an ordinary entity bean and it worked as expected.
To reproduce, first load your pojocache-service.xml into server/all/deploy. I used the pojocache config directly from the user's documentation (after correcting the syntax error on line 50). The only thing I changed was to instruct it to use the JBoss transaction manager:
<!-- Configure the TransactionManager --> <attribute name="TransactionManagerLookupClass"> org.jboss.cache.transaction.JBossTransactionManagerLookup </attribute>
Upon loading, AS logs:
16:09:56,398 INFO [PojoCacheImpl] PojoCache version: JBossCache 'Naga' 3.0.1.GA 16:09:56,424 INFO [PojoCacheImpl] PojoCache version: JBossCache 'Naga' 3.0.1.GA 16:09:56,477 INFO [PlatformMBeanServerRegistration] JBossCache MBeans were successfully registered to the platform mbean server. 16:09:56,483 WARN [NAKACK] max_xmit_size was deprecated in 2.6 and will be ignored 16:09:56,487 WARN [GMS] join_retry_timeout has been deprecated and its value will be ignored 16:09:56,495 INFO [STDOUT] ------------------------------------------------------- GMS: address is 127.0.0.1:34326 ------------------------------------------------------- 16:09:58,504 INFO [RPCManagerImpl] Received new cluster view: [127.0.0.1:34326|0] [127.0.0.1:34326] 16:09:58,506 INFO [RPCManagerImpl] Cache local address is 127.0.0.1:34326 16:09:58,507 INFO [ComponentRegistry] JBoss Cache version: JBossCache 'Naga' 3.0.1.GA
Here is my POJO object as well as my entity bean for comparison:
@Replicable public class PojoEntity implements Serializable{ public int id; public int data; } @Entity @Table(name="myTable") public class PersistentEntity implements Serializable{ @Id @Column(name="id") public int id; @Column(name="data") public int data; }
My bean code is below. I used a stateful bean so I could implement SessionSynchronization to print something and get a warm fuzzy that the transaction manager was doing its thing.
@Stateful(name="container") @TransactionManagement(TransactionManagementType.CONTAINER) public class CMT implements CMTInterface, SessionSynchronization { private static final Integer ID = new Integer(1); @Resource private SessionContext ctx; @PersistenceContext(unitName="myPersist", type=PersistenceContextType.EXTENDED) private EntityManager entityManager; private PojoCache cache; // Question: Is it possible to inject this resource?? public CMT() { MBeanServer server = MBeanServerLocator.locateJBoss(); ObjectName on = null; try { on = new ObjectName("jboss.cache:service=PojoCache"); } catch (MalformedObjectNameException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (NullPointerException e) { // TODO Auto-generated catch block e.printStackTrace(); } PojoCacheJmxWrapperMBean cacheWrapper = (PojoCacheJmxWrapperMBean) MBeanServerInvocationHandler .newProxyInstance(server, on, PojoCacheJmxWrapperMBean.class,false); cache = cacheWrapper.getPojoCache(); cache.start(); // Question: Is it necessary to start cache?? } @TransactionAttribute(TransactionAttributeType.REQUIRES_NEW) public void createEntity() { // Entity Bean PersistentEntity pe = new PersistentEntity(); pe.id = ID; pe.data = 0; entityManager.persist(pe); // Pojo Cache PojoEntity po = new PojoEntity(); po.id = ID; po.data = 0; cache.attach(ID.toString(), po); } @TransactionAttribute(TransactionAttributeType.REQUIRES_NEW) public void printEntity() { // Entity Beqan PersistentEntity pe = entityManager.find(PersistentEntity.class,ID); System.out.println("Entity Bean: " + pe.hashCode() + " data: " + pe.data); // Pojo Cache PojoEntity po = (PojoEntity) cache.find(ID.toString()); System.out.println("Pojo Cache: " + po.hashCode() + " data: " + po.data); } @TransactionAttribute(TransactionAttributeType.REQUIRES_NEW) public void modifyEntity(boolean abortIt) { // Entity Beqan PersistentEntity pe = entityManager.find(PersistentEntity.class,ID); pe.data++; // Pojo Cache PojoEntity po = (PojoEntity) cache.find(ID.toString()); po.data++; if (abortIt) { ctx.setRollbackOnly(); } } public void afterBegin() throws EJBException, RemoteException { System.out.println("After Begin"); } public void afterCompletion(boolean arg0) throws EJBException, RemoteException { System.out.println("After Completion: commit=" + arg0); } public void beforeCompletion() throws EJBException, RemoteException { System.out.println("Before Completion"); } }
When I call the following from a local client bean:
container.createEntity(); container.printEntity(); container.modifyEntity(false); container.printEntity(); container.modifyEntity(true); container.printEntity();
I observe the correct rollback in the entity bean but not in the POJO cache:
16:37:52,429 INFO [STDOUT] After Begin 16:37:52,430 INFO [STDOUT] Entity Bean: 859376458 data: 0 16:37:52,430 INFO [STDOUT] Pojo Cache: 1811335439 data: 0 16:37:52,430 INFO [STDOUT] Before Completion 16:37:52,431 INFO [STDOUT] After Completion: commit=true 16:37:52,431 INFO [STDOUT] After Begin 16:37:52,432 INFO [STDOUT] Before Completion 16:37:52,434 INFO [STDOUT] After Completion: commit=true 16:37:52,434 INFO [STDOUT] After Begin 16:37:52,435 INFO [STDOUT] Entity Bean: 859376458 data: 1 16:37:52,435 INFO [STDOUT] Pojo Cache: 1811335439 data: 1 16:37:52,435 INFO [STDOUT] Before Completion 16:37:52,436 INFO [STDOUT] After Completion: commit=true 16:37:52,436 INFO [STDOUT] After Begin 16:37:52,437 INFO [STDOUT] After Completion: commit=false 16:37:52,438 INFO [STDOUT] After Begin 16:37:52,444 INFO [STDOUT] Entity Bean: 1659856006 data: 1 16:37:52,444 INFO [STDOUT] Pojo Cache: 1811335439 data: 2 16:37:52,444 INFO [STDOUT] Before Completion 16:37:52,445 INFO [STDOUT] After Completion: commit=true
Note the bean is rolled back, the POJO cached object is not.
Hopefully I've justed missed some configuration here. Can anyone help me understand how to get the @Replicable object attached to the current transaction?