• Post Reply Bookmark Topic Watch Topic
  • New Topic
programming forums Java Mobile Certification Databases Caching Books Engineering Micro Controllers OS Languages Paradigms IDEs Build Tools Frameworks Application Servers Open Source This Site Careers Other Pie Elite all forums
this forum made possible by our volunteer staff, including ...
Marshals:
  • Campbell Ritchie
  • Jeanne Boyarsky
  • Ron McLeod
  • Paul Clapham
  • Liutauras Vilda
Sheriffs:
  • paul wheaton
  • Rob Spoor
  • Devaka Cooray
Saloon Keepers:
  • Stephan van Hulst
  • Tim Holloway
  • Carey Brown
  • Frits Walraven
  • Tim Moores
Bartenders:
  • Mikalai Zaikin

Enthuware question doubt

 
Ranch Hand
Posts: 856
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Consider the following code occuring in a MyBean code. It updates the database and sends a message to a queue named Q1. The message driven bean associated with the queue is a BMT MDB. It updates the database within a transaction upon receiving a message.


11. public void myBeanMethod()
12. {
...
21. UserTransaction ut = ejbContext.getUserTransaction();
22. ut.begin();
23. stmt.executeUpdate(query1);
24. queueSender.send(message); //sends a message to a queue Q1.
25. ut.commit();
...
30. }

Assuming that all the variables are properly defined and used, what will happen if the MDB associated with the queue Q1 rolls back the transaction but does not throw any exception?


1. Changes made by the bean code at line 23 will be committed.

2. Line 25 will get a javax.transaction.TransactionRolledbackException

3. Changes made by the bean code at line 23 will be committed but the message sent at line 24 will not be sent.

4. Changes made by the bean code at line 23 will not be committed but there will be no exception.

5. The message will be resent to the MDB.

the correct answer given is 1. But how is that possible, according to me the correct answer 2. :roll:
 
Ranch Hand
Posts: 918
IntelliJ IDE Java Linux
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hi Amandeep

I also find the answer 1 correct - and this because the transaction is committed (on line 23) and the transaction is ended - and once the transaction is ended and committed its result are definitive (the transaction durability rule).
The MDB can have a transaction mechanism but it has its own transaction.

Regards
M
 
Amandeep Singh
Ranch Hand
Posts: 856
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
the MDB associated with the queue Q1 rolls back the transaction but does not throw any exception. So whenever the transaction is rolled back, the database update's are not committed. They are also rolled back.
Am i missing some important point here?
 
Enthuware Software Support
Posts: 4803
52
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hi Amandeep,
The following is the detailed explanation given with the question -


An important point to remember here is that only the sending of the message is a part of the transaction. Whether the MDB receives the message or consumes it does not affect MyBean's transaction. Further, the client's transaction context is never passed to a MDB. The container creates a new transaction context for a MDB if it requires a transaction. So, if the MDB rolls back its transaction, it does not affect the message sender's transaction.

The second point is that if a BMT MDB does not throw any exception while processing the message (Note: It can only throw Runtime or EJBExceptions from onMessage()), the message is considered to be consumed. On the other hand, if the onMessage() method throws an exception, the exception is logged, the MDB instance is discarded, and the transaction is rolled back. The message is redelivered (to a different MDB instance). How many times a message can be redelivered depends on the container.

Therefore, in this case, MyBean's transaction will commit without any problem. The message will not be redeliverd because the MDB did not throw any exception.

Note that, in case of a CMT MDB (with transaction attribute of REQUIRED), the container starts a transaction before dequeuing the message. So, if the bean throws a system exception, or calls setRollbackOnly(), the message will be redelivered.


HTH,
Paul.
 
Amandeep Singh
Ranch Hand
Posts: 856
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Thanks Paul for your reply. I have already the explanation with me-

Therefore, in this case, MyBean's transaction will commit without any problem. The message will not be redeliverd because the MDB did not throw any exception.




the question says- if the MDB associated with the queue Q1 rolls back the transaction but does not throw any exception. So does it means that rollback the transaction has not affect on the MDB because only the sending of the message is a part of the transaction.

it looks weird.
 
Ranch Hand
Posts: 210
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Whatever happens in your MDB will not affect the transaction commit in the original bean("MyBean" or the Message sender)....The sender bean's job is just to send the message, it definitely wont wait for the MDB to pick up that message.
In your case, the code shown is of the Sender bean and not the MDB, hence the transaction will get committed...
 
Amandeep Singh
Ranch Hand
Posts: 856
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Thanks Rahul,

i got it, the code above shown is of sender only. The sender is sending the message to MDB. And the transaction is rolled back for MDB not of sender code.


Intially i thought this code to be MDB code and it's transaction is rolled back.
 
Mihai Radulescu
Ranch Hand
Posts: 918
IntelliJ IDE Java Linux
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hi Paul,

may be I am wronkg but I find a little failure in your arguments - at least on the first one.


An important point to remember here is that only the sending of the message is a part of the transaction. Whether the MDB receives the message or consumes it does not affect MyBean's transaction. Further, the client's transaction context is never passed to a MDB. The container creates a new transaction context for a MDB if it requires a transaction. So, if the MDB rolls back its transaction, it does not affect the message sender's transaction .



If the MyBean (CMT) uses a requred transaction (with transaction attribute of REQUIRED) then the MDB must join the its transaction with the one from the MyBean. So in this case if the MDB will rolls back its transaction this will roll back the MyBean transaction also - because they are joined. See the bold text.


Am I wrong ?

Regards,
M
 
Amandeep Singh
Ranch Hand
Posts: 856
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Yes, you are right. From the specifications-

Refer to section 13.2.2

It says actually sending message and then dequeuing of the message and then updating the database under CMT, can be part of a single transaction.



The Enterprise JavaBeans architecture makes it possible for an application program to send messages to
or receive messages from one or more JMS Destinations and/or to update data in one or more databases
in a single transaction.

In the following figure, a client invokes the enterprise bean X. Bean X sends a message to a JMS queue
A and updates data in a database B using connections that the Deployer configured to connect with a
JMS provider and a database. Then X calls another enterprise bean, Y. Bean Y updates data in database
C. The EJB server ensures that the operations on A, B, and C are either all committed, or all rolled
back.

The application programmer does not have to do anything to ensure transactional semantics. The enterprise
beans X and Y perform the message send and database updates using the standard JMS and
JDBC™ APIs. 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 ensure atomic
updates across all the three resources.





Section 13.6.3.2
Opposite to above specifications it also says- :roll:


A transaction must be started before the dequeuing of the JMS message and, hence, before the
invocation of the message-driven bean’s onMessage method. The resource manager associated
with the arriving message is enlisted with the transaction as well as all the resource managers
accessed by the onMessage method within the transaction. If the onMessage method
invokes other enterprise beans, the container passes the transaction context with the invocation.
The transaction is committed when the onMessage method has completed. If the
onMessage method does not successfully complete or the transaction is rolled back, message
redelivery semantics apply.

 
Ranch Hand
Posts: 342
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Opposite to above specifications it also says ...


Actually there is no contrast between 13.2.2 and 13.6.3.2:
13.2.2 only says that the following actions triggert by bean X can be part of a transaction

a) X sends a message to queue A
b) X updates db B
c) X invokes Y
d) Y updates db C

But the spec doesn't require that receiving and processing the message from queue A by a MDB
is also part of the transaction. It only says if that transaction is rolled back, no message will be send
and no databases will be updated.

As a rule: If the client sends a message within a transaction, the message will be send physically
when the transaction commits.

So, if the MDB receives the message, the client's transaction has already commited. Therefore
the MDB's transaction doesn't influence client's transaction.

That's a grat difference between asynchronous messaging and and synchronous messaging using
session beans.

according to me the correct answer 2



Have a look at the tables 19, 20 in core spec 14.3.4: They show that a MDB-client never receives an
exception from a MDB. Here, exceptions are always propagated to the resource adapter.



 
Don't get me started about those stupid light bulbs.
reply
    Bookmark Topic Watch Topic
  • New Topic