Hello all: Page 78 of the spec says the following:
Session bean methods invoked by the client in this transaction can now be delegated to the bean instance. An error occurs if a client attempts to invoke a method on the session object and the deployment descriptor for the method requires that the container invoke the method in a different transaction context than the one with which the instance is currently associated or in an unspecified transaction context.
I'm not quite clear on this. In what case would an error occur if "the method requires that the container invoke the method in a different transaction"? Let's say a method's transaction attribute is RequiresNew. I would think that a new transaction would be created and the method would run in that transaction. Maybe I'm reading this statement incorrectly. Can someone please clear this up. Thanks,
Let's say a method's transaction attribute is RequiresNew. I would think that a new transaction would be created and the method would run in that transaction.
What you say here is correct except the last sentence. In this case, the method will not run in the transaction instead according to the spec it will throw an error.
An error occurs if a client attempts to invoke a method on the session object and the deployment descriptor for the method requires that the container invoke the method in a different transaction context than the one with which the instance is currently associated or in an unspecified transaction context.
The spec clearly states that when a client in transaction invokes a method on the session object which has transaction attributes ( RequiresNew or NotSupported ), the container will throw an error. I guess i have made u clear.
Thanks Reghu: The meaning of the spec is not clear to me. Are you CERTAIN, that's the meaning, or is that your interpretation. Why would a method using RequiresNew throw an exception? That means that you could never call that method if the client is currently in another transaction context. My understanding is that a new transaction context would be created and the callers transaction context would be suspended.
If a session bean instance is participating in a transaction, it is an error for a client to invoke a method on the session object such that the transaction attribute in the deployment descriptor would cause the container to execute the method in a *different transaction context* or in an unspecified transaction context. In such a case, the container throws the java.rmi.RemoteException to the client if the client is a remote client, or the javax.ejb.EJBException if the client is a local client.
How can i know that is different transaction frop current? Pls help me....
Hi, As for my understanding regarding this issue is this In stateful bean transaction can run more than one method and it has no boundary condition like if it starts from one method and it can be end in second method or third whatever, So just imagine this in current scenario that transaction begins from method 1 which has a transaction tx A (Required etc),so instance will associate with this transaction context and it keeps continue method 2 or method 3 until some method 4 which has different transaction context may be in the case of RequiresNew,NotSupported etc and still the previous transaction is still continue and new method in this case method 4 wants to continue new transaction(RequiresNew) which is defined in deployment descriptor,the container will throw the error because nested transaction is not allowed in EJB 2.0 so any method in stateful bean will start the new transaction which has to make sure that no other transaction should run before. On the other hand transaction is running and method 4 runs in unspecified transaction in case of NotSupported so the condition is, bean instance should not associate with any transaction context and it must complete the transaction before method 4 which started in method 1. I hope this makes you clear. Regards,
Howdy Keith, Does that answer your question? Nauman gave what I consider the best description of what's happening, but I also think that the way this is described on page 78 is VERY confusing. I'll try another summary, just because I think it's confusing, too. Bean A is a CMT bean. Inside Bean A you have: methodOne() with a TX attribute of Required methodTwo() has a TX attribute of RequiresNew Now imagine Client Foo is involved in a transaction "bar" when he invokes methodOne(). Now methodOne runs in transaction "bar". But the transaction does not END there... because it is the CLIENT (i.e. the caller of methodOne()) who controls the transaction demarcation for "bar". In other words, transaction "bar" will not end (commit or rollback) until client Foo ends that transaction. If client Foo is a BMT bean, then transaction "bar" will not end until client Foo calls commit() or rollback() (or throws a system exception). If client Foo is a CMT bean, then transaction "bar" will not end until the particular method in which this transaction began has completed. So imagine client Foo has a single transactional CMT method, and inside that method client Foo invokes first methodOne, which then picks up the transaction "bar" and runs methoOne within that transaction. From this point on, the session bean is now participating in transaction "bar", and transaction "bar" has not yet completed! Now, client Foo then immediately turns around and invokes methodTwo on the bean. Here is the problem! MethodTwo is set to "RequiresNew" in the DD, but the "bar" transaction has not yet completed. So the container freaks out. The reason this is often confusing is because you might be tempted to think, "How is this any different from any OTHER scenario in which the container will use RequiresNew to simply suspend the current transaction, run the method with a new transaction, and then resume the original transaction again when the method completes. But... the scenarios are different. How are they different? The difference is in whether the BEAN is already IN a transaction or not!! In other words, in the normal (non-exception-throwing) scenario, the BEAN is not already in a transaction. The incoming CALL is in a transaction, but that's OK, the container just suspends that transaction temporarily. But in the problem scenario, the bean itself is already said to be IN an open transaction, not just the incoming client call, but the actual bean! So the bean is sitting there waiting for this transaction to complete... somehow... and now a call comes in to a bean method that demands a NEW transaction (because the bean method is marked "RequiresNew"). The container cannot allow a new transaction within an already open transaction. The container is allowed to suspend the CLIENT's incoming transaction in order to start a new one. But the container is NOT allowed to suspend the BEAN's currently-open transaction in order to start a new one for a different method of the bean. That's just not allowed because, as was said earlier, that would be a 'nested' transaction which is not permitted (and if it were, it would open up a whole new can of worms to deal with -- a whole new set of rules for what happens if one of the participants in the nest hierarchy does not commit...) This is a confusing one, Keith, but as I've said to you before... I consider it a VERY good sign on your part that you're looking at the spec in this level of detail. Most people (including me) often look at these bullet points and assume it makes sense without really looking at it seriously and trying to work it out. This is an excellent spec, in terms of reader-friendliness, but there are still a LOT of areas where it isn't as clear as it could be. There are a few spots where I have sat with the guy who actually DEVELOPED the container for Sun's EJB reference implementation, and HE still wasn't always 10000% certain of what a particular phrase was intended to say. He did know how it really worked, but he wasn't always able to figure out why they wrote something in the spec in a particular way. Or sometimes you have to look at two different places in the spec in order to figure out what's really happening. Anyway, cheers and good luck. Aren't you taking the test really soon?? Kathy
Joined: Nov 25, 2003
Thanks Kathy and all others who contributed to this thread. It's much clearer now. So to summarize, if a method of bean A is called by a client which is currently running in transaction context B and that method has an transaction attribute that causes that method to also run in transaction context B, another method of A that causes it to run in a different transaction context may not be called until transaction B is complete. The three transaction attributes that would cause bean A to run in a different transaction context would be NotSupported, RequiresNew or Never. So a bean can only execute in one transaction context at a time. I hope to ready for the exam within the next couple weeks. If I keep getting great answers like this I expect I'll do very well. Thanks again.
[ December 26, 2003: Message edited by: Keith Rosenfield ]
I think it would help if we had a handle for this somewhat surprising state that a CMT bean can find itself in. Let's call it "turquoise", just for fun. turquoise: A CMT bean that has at one time participated in a still-open transaction. So methods may end, but since the transaction is still open, it turns the whole bean this lovely color. And it stays that way until the transaction that 'tinted' the bean (or should that be 'tainted' the bean) is closed. Since the event that finally closes the transaction may be in some far-away land, it might look like the bean magically looses it's color (ugh). Anyway, given the definition, the rule would be pretty straight-forward: "You can't call a method that requires a new transaction on turquoise beans" Is that right? --Dale--
The container is allowed to suspend the CLIENT's incoming transaction in order to start a new one. But the container is NOT allowed to suspend the BEAN's currently-open transaction in order to start a new one for a different method of the bean. That's just not allowed because, as was said earlier, that would be a 'nested' transaction which is not permitted (and if it were, it would open up a whole new can of worms to deal with -- a whole new set of rules for what happens if one of the participants in the nest hierarchy does not commit...)
I'm trying to understand it fully...I almost got ur point...but still have a doubt.........in pg. 515 ..the step 3 cmtMandatory() is followed by reqNew() ..If the container is NOT allowed to suspend the BEAN's currently-open transaction in order to start a new one for a different method of the bean...then why is it ok here?? why is it not ok with Required... I'm not getting into my brain.Pls help
There is never a nested transaction. What happens is that c.cmtMandatory() runs in the existing client transaction (tx 1). tx 1 is then suspended (for c.cmtRequiresNew()) in order to start a new transaction (tx 3).