Discussions

EJB design: EJB 2.0 spec oversight?

  1. EJB 2.0 spec oversight? (8 messages)

    In the specification of MessageDriven beans, the 2.0 spec is ambiguous (or lacking) with respect to transactional integrity of the EJB and JMS systems. The spec states:

    "If the message-driven bean uses container managed transaction demarcation, message acknowledgment is handled automatically as part of the transaction commit."

    Presumably the transaction they are talking about is the EJB transaction, not a JMS transaction. That is fine for handling the ACK of the message, but there is a lot more to it in a real-world application.

    A common use for message beans will be to implement asyncrounous procesing in EJB-based application servers. A common scenario is that a message bean will do some entity bean manipulations and then send JMS messages to start other async message beans running. E.g. message beans will call other messages beans via async JMS messages.

    The problem is, there is no way for the bean developer to insure transaction integrity of the system. If a message bean rolls back its (EJB) transaction, any entity bean changes it made are discarded, but JMS messages it has posted are NOT discarded. In effect, the work scope of
    the bean is not rolled back. No matter how carefully the message bean is coded, it will be possible for entity beans and message queues to get out of sync.

    IMHO, the spec should specify (1) that a message bean operates within a JMS transaction which is started by the container before the onMessage() of the bean is called, and (2) the JMS transaction is rolled back or committed along with the EJB transaction. Since the onMessage() method (by definition) must be TX_REQUIRED (or TX_NONE), the scope of the EJB transaction is only the onMessage() -- it does not need to be coordinated with any larger incoming EJB transaction. This should not be hard for a container to implement.

    A bean developer can *almost* do this in the message bean itself by starting a JMS transaction on entry and carefully rolling back the JMS transaction anytime the bean calls to rollback the EJB transaction. Before returning from onMessage(), the bean would commit the JMS transaction. With careful try/catch this is almost sufficient, but the container can still rollback the transaction (for other reasons) after the onMessage() returns and then it is too late because the JMS messages would already be comitted. Only the container could do this reliably.

    To me, this seems like an important aspect of joining the EJB and JMS technologies which the EJB 2.0 spec attempts to do. The lack of a coordinated transaction seems to severly limit the usefulness of message beans in building a robust EJB-based server application.

    Any thoughts?
    -Mark McMillan

    Threaded Messages (8)

  2. EJB 2.0 spec oversight?[ Go to top ]

    Mark-

    You are dead on here. The only way to have true JMS transaction session / JTA User Transaction propagation is if the JMS engine and the transaction monitor are implemented in the same application server.

    At BEA, our engineers ran into this problem very early on. If all of your code is implemented on WebLogic, you are safe, but you will run into issues if you are hosting message driven beans in WebLogic (with WLS UserTransactions), but having them consume messages from another JMS provider (who is hosting the JMS transacted sessions).

    At BEA, they implemented a proprietary hook in their JMS code that says "infectSession()" that infects a JMS transacted session with a UserTransaction. The JMS transacted session then follows the life cycle of the user transaction and will be committed when the user transaction is committed.

    There is a little more depth to this than what I'm listing here, but you have definitely hit the nail on the head: MDBs aren't completely portable between JMS servers and application servers.

    Take it easy...
    Tyler
  3. EJB 2.0 spec oversight?[ Go to top ]

    I have the same question on using JMS transaction inside
    a CMT MDB, when you creeate a JMS session, the transaction
    flag is either true or false, but what needed for "ALL OR
    NOTHING" semantic is a third flag says SUPPORTS, which enable inherit transaction context from the onMessage method.
  4. EJB 2.0 spec oversight?[ Go to top ]

    from Sun's J2EE 1.3 RI beta,
    JMS tutorial

    <quote>
    When you create a [JMS] session in an enterprise bean, the container ignores the arguments you specify, because it manages all transactional properties for enterprise beans. It is still a good idea to specify arguments of true and zero to the createQueueSession or createTopicSession method to make this situation clear:

    queueSession = queueConnection.createQueueSession(true, 0);

    When you use container-managed transactions, you usually specify the Required transaction attribute for your enterprise bean's business methods.
    You do not specify a message acknowledgment mode when you create a message-driven bean that uses container-managed transactions. The container handles acknowledgment automatically.

    If a message-driven bean uses container-managed transaction demarcation, the container acknowledges the message as a part of the transaction commit.
    </quote>


  5. EJB 2.0 spec oversight?[ Go to top ]

    Reading through chapter 16 of the spec (2.0 Proposed Fianl Draft October 23, 2000) "Support for Transactions"... section 16.2.2 describes exactly the scenario I am concerned about -- an EJB posts messages to a JMS queue and updates two databases in a single transaction. The spec says quite explicity that the JMS and database updates are a single atomic operation:

    "Behind the scenes, the EJB Server enlists the session on the connection to the JMS provider and the database connections as part of the transaction. When the transaction commits, the EJB Server and the messaging and database systems perform a two-phase commit protocol to insure atomic updates across all the three resources."

    Also, section 16.3.5 "Use of JMS APIs in transactions" is explicit on the issue, going so far as to say the 'transacted' flag on the JMS createQueueSession() API is ignored because the container will *always* enlist the JMS sesison into the EJB transaction. But how can the container do this (ignore the flag) if JMS is being provided by a different vendor... how does the container intercept the createQueueSession() API call to JMS? That does not make sense...

    I *think* this requires that the databases and the JMS provider must support the XA protocol for this to work (short of a vendor-specific back door hook). And somehow the container must be aware of the JMS provider, e.g. it must be named in the deployment descriptor somewhere, but I don't see that specified anywhere.

    It is not clear to me if the spec says this behaviour (a single atomic transaction) is a *required* behaviour that a bean writer can depend on, or is optional. That seems like an essential point to this bean writer...!

    -Mark McMillan
  6. EJB 2.0 spec oversight?[ Go to top ]

    There is a little more depth to this than what I'm listing here, but you have definitely hit the nail on the head: MDBs aren't completely

    >portable between JMS servers and application servers.

    If this turns out to be true, then Sun missed the boat big time with EJB 2.0 and the whole concept of message driven beans.

    -Mark
  7. EJB 2.0 spec oversight?[ Go to top ]

    There is a little more depth to this than what I'm listing here, but you have definitely hit the nail on the head: MDBs aren't completely

    >portable between JMS servers and application servers.

    This is not true.

    I am amazed that a vendor thinks that transactional message consumption requires proprietary hooks ... good for other vendors.
  8. EJB 2.0 spec oversight?[ Go to top ]

    I think you guys are missing my point:

      - First... I'm not really a vendor. I wouldn't presume to speak on behalf of our engineers -- I just try to aid the community in its understanding.
      - Second, any MDB container can consume messages from another JMS server, but the issue lies around whether or not the message consumption of the JMS transacted session and a separately started UserTransaction in the app-server can truly be made into one unit. This definitely can be done, but not in a platform-independent way. The JMS server and application server would require hooks to accomplish this. If you don't have these hooks, the container will still work, you just run a risk by having two transactions that aren't joined at the hip.
      - I'm familiar with WebLogic SP1 which was released a few days ago adding some additional functionality to integrate foreign JMS providers with the application server. There are some more flags that you have to identify and the preference is that the JMS provider support XA transactions for the safest operation.
  9. EJB 2.0 spec oversight?[ Go to top ]

    Mark, Sun hasn't missed any boat w.r.t. MDB's -- they just need to tidy up the wording of the spec. A JMS resource should be like any other XA transactional resource & should be able to join any XA transaction manager. If this doesn't happen, I would bet it's usually a vendor problem (though in fairness exacerbated by spec ambiguity).