3 Replies Latest reply on Jun 12, 2008 3:12 PM by timfox

    Clearing up confussion

    ejb3workshop

      Maybe I didn't explain is correctly. I am sending a message as well as persisting and entity. Since I would like to use XA, I'd expect both to succeed. For this to be the case the entity should be persisted and the message should be placed on the queue. However the message is already being received on the other end by the next bean, while the entity is not yet persisted. I am not too concerned about the order these happen in, as long as they happen as one unit of work.

      As soon as I use the JmsXA factory this problem goes away, which seem to me like the correct behaviour.


        • 1. Re: Clearing up confussion
          timfox

           

          "ejb3workshop" wrote:
          Maybe I didn't explain is correctly. I am sending a message as well as persisting and entity. Since I would like to use XA, I'd expect both to succeed. For this to be the case the entity should be persisted and the message should be placed on the queue. However the message is already being received on the other end by the next bean, while the entity is not yet persisted.


          Yes, that can happen with XA even though they are both in the same tx!

          This is what happens (simplified):

          1. JTA tx starts to commit
          2. Commit called on jms xa resource - message gets sent

          3. Commit called on db xa resource - row gets stored in DB
          4. JTA tx has finished committing

          Now, between 2 and 3 since it takes a finite time, the message can hit the queue, get consumed, and the consumer won't find the row in the db since the original tx has not finished committing yet.



          • 2. Re: Clearing up confussion
            ejb3workshop

            But then it wouldn't be atomic, nor consistent or durable. What happens in this case if 3 should fail and the transaction has to be rolled back ?


            • 3. Re: Clearing up confussion
              timfox

               

              "ejb3workshop" wrote:
              But then it wouldn't be atomic, nor consistent or durable. What happens in this case if 3 should fail and the transaction has to be rolled back ?


              Actually it is all three of those, and you missed the I (Isolated) ;)

              In a 2pc protocol, all participants have already voted ok to prepare() by the time commit is called on them by the transaction manager.

              If 3) fails then depending on why it failed, the transaction manager will kick int he recovery protocol, and retry calling commit on it until it eventually commits.

              In some cases a "heuristic" outcome may be required - i.e. manually intervention to commit the branch.

              But voting ok to prepare basically means "I have all the data I need to commit" so in principle I can commit.

              As I say, this is all standard XA/JTA, nothing new here.

              I'd suggest a look at the XA spec (it's not a fun read), but you can probably google and find lots of resources about 2PC, also recovery protocols.