6 Replies Latest reply on Jun 25, 2004 4:56 AM by aloubyansky

    Problem with CMR and transaction, need help

      Hello,
      I have a question and would really appreciate if anyone could spend time to answer this question.

      I use EJB 2.0 and in the session bean I use Container Managed Transaction.
      My application server is JBOSS 3.2.4RC1.


      There two tables and they have one to many relationship. Queue has many Requests.
      I have a method in Session Bean to delete one queue and on this method,
      transaction type="Required" is defined. I only want to delete it if there is no request in queue, so I need to check whether queue is empty.

      public void deleteQueue(String queueName) {
      Collection requests = queueLocal.getRequests(); //get requests via CMR
      if (requests.size() <= 0) {
      queueLocal.remove();
      }


      So far everything works fine.

      The problem come when I have a method where I want to delete many queues.
      In that method I iterate queue names and call deleteQueue in each
      iteration. In this method I define transaction type="Never".

      public void deleteQueues(String[] queueNames) {
      for (int i=0; i<queueNames.length; i++) {
      deleteQueue(queueNames);
      }
      }
      It throws exception :
      16:35:20,328 ERROR [LogInterceptor] RuntimeException:
      java.lang.IllegalStateException: A CMR collection may only be used within
      the transction in which it was created
      at
      org.jboss.ejb.plugins.cmp.jdbc.bridge.RelationSet.getIdList(RelationS
      et.java:66)
      at
      org.jboss.ejb.plugins.cmp.jdbc.bridge.RelationSet.size(RelationSet.ja
      va:74)


      I saw similar problem in the forum and one of the solution given was to use User transaction. So far I do not see why user or Container managed
      transaction should behave differently , so I do not want to use it as long
      as I do not understand why.

      Thanks in advance.
      Bassie

        • 1. Re: Problem with CMR and transaction, need help
          aloubyansky

          When there is a transaction, there is no difference between CMT and UserTransaction. In your case there is no transaction.

          • 2. Re: Problem with CMR and transaction, need help

            thank you for the reply,
            In my case I defined the transaction using xdoclet, I put my snipped ejb-jar below. I would like to work with CMT. I think there is transaction here. What is the reason actually the exception thrown when I invoke size() method in Collection ? This part make fail.

            I would appreciate your further answer.

            <container-transaction >

            <ejb-name>QueueManagement</ejb-name>
            <method-intf>Local</method-intf>
            <method-name>deleteQueue</method-name>
            <method-params>
            <method-param>java.lang.String</method-param>
            </method-params>

            <trans-attribute>Required</trans-attribute>
            </container-transaction>
            <container-transaction >

            <ejb-name>QueueManagement</ejb-name>
            <method-intf>Remote</method-intf>
            <method-name>deleteQueue</method-name>
            <method-params>
            <method-param>java.lang.String</method-param>
            </method-params>

            <trans-attribute>Required</trans-attribute>
            </container-transaction>
            <container-transaction >

            <ejb-name>QueueManagement</ejb-name>
            <method-intf>Local</method-intf>
            <method-name>deleteQueues</method-name>
            <method-params>
            <method-param>java.lang.String[]</method-param>
            </method-params>

            <trans-attribute>Required</trans-attribute>
            </container-transaction>
            <container-transaction >

            <ejb-name>QueueManagement</ejb-name>
            <method-intf>Remote</method-intf>
            <method-name>deleteQueues</method-name>
            <method-params>
            <method-param>java.lang.String[]</method-param>
            </method-params>

            <trans-attribute>Required</trans-attribute>
            </container-transaction>

            • 3. Re: Problem with CMR and transaction, need help
              cvandyck

              Try putting some transactional debugging in your code, especially in the deleteQueue(String queueName) method.

              Use this class to help determine if there is a transaction in your deleteQueue method when you are deleting multiple queues.

              import javax.naming.InitialContext;
              import javax.transaction.Status;
              import javax.transaction.TransactionManager;
              
              
              /**
               * @author Collin VanDyck
               *
               */
              public class TransactionInfo {
              
               public static final String getTransactionInformation()
               {
               String result = "";
              
               try
               {
               TransactionManager tm = (TransactionManager) new InitialContext().lookup("java:/TransactionManager");
               int status = tm.getStatus();
              
               switch (status)
               {
               case Status.STATUS_ACTIVE:
               result = "ACTIVE";
               break;
               case Status.STATUS_COMMITTED:
               result = "COMMITTED";
               break;
               case Status.STATUS_COMMITTING:
               result = "COMMITTING";
               break;
               case Status.STATUS_MARKED_ROLLBACK:
               result = "MARKED_ROLLBACK";
               break;
               case Status.STATUS_NO_TRANSACTION:
               result = "NO_TRANSACTION";
               break;
               case Status.STATUS_PREPARED:
               result = "PREPARED";
               break;
               case Status.STATUS_PREPARING:
               result = "PREPARING";
               break;
               case Status.STATUS_ROLLEDBACK:
               result = "ROLLEDBACK";
               break;
               case Status.STATUS_ROLLING_BACK:
               result = "ROLLING_BACK";
               break;
               case Status.STATUS_UNKNOWN:
               result = "UNKNOWN";
               break;
               default:
               result = "UNDEFINED";
               }
               }
               catch (Exception e)
               {
               result = "ERROR: could not get tx status: " + e.getMessage();
               }
              
               return result;
               }
              
              }
              


              Use that class and let us know the transactional status when you are deleting a specific queue, as called by your deleteQueues() method.

              My guess is that, as lou mentioned, there is not a transactional context.



              • 4. Re: Problem with CMR and transaction, need help
                aloubyansky

                In the previous post you wrote that tx attribute is Never. So there is no tx. CMR collection was created in a tx and accessed then w/o tx.

                • 5. Re: Problem with CMR and transaction, need help

                  Thanks Collin,
                  It's nice debug tool. When I specify Tx=Required in deleteQueue and Tx=Never in deleteQueues, then I call deleteQueues method, I got this:

                  10:39:50,062 INFO [STDOUT] delQueues Tx status: NO_TRANSACTION
                  10:39:50,062 INFO [STDOUT] delQueue Tx status: NO_TRANSACTION
                  10:39:50,078 ERROR [LogInterceptor] RuntimeException:
                  java.lang.IllegalStateException: A CMR collection may only be used within the tr
                  ansction in which it was created
                  at org.jboss.ejb.plugins.cmp.jdbc.bridge.RelationSet.getIdList(RelationS
                  et.java:66)
                  at org.jboss.ejb.plugins.cmp.jdbc.bridge.RelationSet.size(RelationSet.ja
                  va:74)

                  If I specify Tx=Required in deleteQueue and don't specify any Tx type id deleteQueues, I got this:

                  11:07:51,093 INFO [STDOUT] delQueues Tx status: ACTIVE
                  11:07:51,093 INFO [STDOUT] delQueue Tx status: ACTIVE
                  Then I have a problem, because for example I want to delete 5 queues and one failed then everything rollback, instead, I still want to delete the other four.

                  My objective is that client will be able to delete single queue or multiple. Deleting multiple queues will not be rollback if one failed.

                  For Alexey, I'm sorry posting the wrong ejb-jar, below is the right one.
                  <container-transaction >

                  <ejb-name>QueueManagement</ejb-name>
                  <method-intf>Local</method-intf>
                  <method-name>rmDeleteQueues</method-name>
                  <method-params>
                  <method-param>java.lang.String[]</method-param>
                  </method-params>

                  <trans-attribute>Never</trans-attribute>
                  </container-transaction>
                  <container-transaction >

                  <ejb-name>QueueManagement</ejb-name>
                  <method-intf>Remote</method-intf>
                  <method-name>rmDeleteQueues</method-name>
                  <method-params>
                  <method-param>java.lang.String[]</method-param>
                  </method-params>

                  <trans-attribute>Never</trans-attribute>
                  </container-transaction>

                  I highly appreciate your help.

                  • 6. Re: Problem with CMR and transaction, need help
                    aloubyansky

                    The use RequiresNew for deletion of each queue. But access CMP in transaction.