8 Replies Latest reply on Sep 12, 2004 2:04 PM by oferbaranes

    transaction rollback instead of wait

    oferbaranes

      i have an 2 MDBs, the first load&modify an cmp entity bean,but not commit
      yet,then it send message to the other mdb which try to load(read only) the same entity bean (which is dirty,before commit) ,now,instead to wait to the fisrt tx to commit ,the second tx immediatly fails with 'rollback ,possibaly a timeout' , where actually the whole process take less the a second and it can't be timeout!,
      as far as i now on pessimistic lock,which i use,the tx2 should have wait to
      the first to commit ,but it didn't,why?who could have mark tx2 as rollback?!

      i am using pessimistic lock, commit option A,CMT MDB,Jboss 3.2.3,Postgres 7.3,isolation level read commited.

        • 1. Re: transaction rollback instead of wait
          jamesstrachan

          It's very difficult to tell what is happening here.

          It could be a database locking problem. You can test this using SQL commands outside the application server.

          Or it could be a JBoss locking problem, as JBoss also operates a locking strategy on entity beans.

          Or it could be a locking problem on the message queues if placing the message from MDB1 to MDB2 on the queue is included in the uncommitted transaction.

          And how are you preventing the commit executing in the first MDB ? Normally, the transaction would automatically commit once the onMessage() method runs to completion.

          Either way, the real problem is that you are trying to carry out a second operation (in the second MDB) on the entity bean before completing the first.

          I would suggest two alternatives :-

          1. Perform a commit in the first MDB (which should include the three operations of removing Message 1 from the queue, updating the entity bean and enqueing the message to MDB2). Then MDB2 has a clean operation.

          2. Refactor so that the work done in MDB2 is performed iin MDB1.

          James




          • 2. Re: transaction rollback instead of wait
            oferbaranes

            1 - if MDB1 send message to MDB2 in one of it's onMessage()
            used method , how can you gurentee that MDB1 commit before MDB2
            will start ?
            2- both MDBs are using the same Queue (different selector) with
            AUTO_ACKNOWLEDGE , is that adding light ?

            • 3. Re: transaction rollback instead of wait
              jamesstrachan

              I guess that you could get a race between MDB2 starting and MDB1 committing if (a) you use a file based JMS persistence manager and (b) you are not including the JMS messages in the transaction. Then it is possible for the thread running MDB2 to start before the thread in MDB1 has finished.

              That would suggest that, if you persevere with this architecture, you should use a JDBC based persistence manager and include handling JMS messages within the transaction. That involves getting a reference to the Transaction Manager and calling the begin() and commit() methods on it.

              Making message handling transactional also avoids problems if the database commit fails but the messages are still processed.

              I think, however, that refactoring would almost certainly be a quicker and more reliable method of resolving the problem.

              If you can tell me what your application is trying to do, I may be able to suggest an alternative design pattern.

              James

              • 5. Re: transaction rollback instead of wait
                oferbaranes

                it's ok if thread2 will not be able to see the changed data
                before the commit,why it doesn't wait() to the commit,why instead it rollback ?!

                • 6. Re: transaction rollback instead of wait

                  You tell me, you've got access to server.log and log4j.xml to set TRACE logging if
                  needed.

                  Another FAQ for you:
                  http://www.jboss.org/wiki/Wiki.jsp?page=JBossForums

                  • 7. Re: transaction rollback instead of wait
                    oferbaranes

                    i guess that the second tx didn't wait at all (for sure not till timeout) since
                    it was marked for rollback ,and it was marked for rollback because of
                    a deadlock which has no trace on the jboss log , as i get deeper in my system i found that deadlocks may occur (and even saw one,after
                    code change) , i assume that jboss just 'forgot' on a certain flow to trace
                    the deadlock.

                    • 8. Re: transaction rollback instead of wait
                      oferbaranes

                      last one:

                      I have found in my code a 'catch(Excetion e)' around the the code where the deadlock tookplace and the tx was marked for rollback,the catch has no trace inside it,and there for i could never know that there was a rollback as to a deadlock,in the followed lines i only got TransactionRollBackedException without any good explantion.

                      As to JBoss logs,on 3.2.5,the DeadlockDetector doesn't trace the deadlock but only throw it as exception ,which means that bad code of exception handling (as mine) will lose this very critical piece of information , that's the code

                      if (set.contains(holding))
                      {
                      // removeWaiting should be cleaned up in acquire
                      String msg = "Application deadlock detected,
                      resource="+resource
                      +", holder="+holder+",
                      waitingResource="+waitingFor
                      +", waitingResourceHolder="+holding;

                      //NO TRACE HERE !!!

                      throw new ApplicationDeadlockException(msg, true);
                      }



                      Adrian , this might be good to pass to developers to add a trace :-) ,
                      thanks