1 Reply Latest reply on Dec 10, 2008 6:34 PM by Jason Greene

    Container managed transactions in JBoss AS 5.0

    David Sundstrom Newbie

      Just 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?



        • 1. Re: Container managed transactions in JBoss AS 5.0
          Jason Greene Master

          Did you enable load-time instrumentation on AS5 (or alternatively use aopc - not preferred)?

          There are two steps to do this:

          1) Enable use of the pluggable-instrumentor
          by adding the following to your run.conf:

          JAVA_OPTS="$JAVA_OPTS -javaagent:$DIRNAME/../server/all/deployers/jboss-aop-jboss5.deployer/pluggable-instrumentor.jar"
          


          2) Enable load time weaving in server/all/conf/bootstrap/aop.xml:

          <property name="enableLoadtimeWeaving">true</property>
          ...
          <property name="include"> <!-- Add your package prefixes here --> </property?