I'm looking for a good explanation of container managed transactions. At my company we have an EJB app in which we are trying to set CMT attributes on. It's strucured in a way that each table in our DB has a corresponding entity bean. (we use BMP entity beans) The app is already developed mostly (its in alpha) and none of us here understand enough about how to declare container transactions in a production app. We all know what they are (the six different kinds) and how they all work. What we're looking for is a practical example (not like the dumbed down textbook examples) of how you would use them in a production app. All of us here are stuck on the programmatic way of thinking and I know this is wrong when using CMT. So, this is the example. We have a submitOrder method that appears to be causing rollbacks/deadlocks (because we set every method's tx attribute to Required as a starting point). The submitOrder implementation is as follows:
submitOrder
For Each lineItem
lookup lineItem product
adjust lineItem price using product
End For
set orderHead status finalized
end submitOrder
We have reason to believe that the rollback/deadlock comes from reading the product table from within a tx and thus locking certain product entities. The scenario goes as follows. User1 needs products A, B, and C. User2 needs products C, B, and A. When user1 reads A he is pre-empted by user2 who grabs C & B. Now user1 tries for B but has to wait for user2 who is waiting for the A that user1 has a lock on. There is no reason for the problem to occurr any place else because each user maintains his/her own set of lineItem transactions and works off of his/her own order record. So the question is this.
How would you set tx attributes to allow the method body to be in a transaction while not pulling the product entities into the transaction? 1st idea is to set the transactional attribute of the read method of the product entity to NotSupported. This is no good because there are other places in our app where we need to read the product within the context of an existing transaction. Next idea is to mark the read method on the product bean supports. However, that puts us right back where we started because the products will be read within the transaction causing deadlocks/rollbacks. So now I'm thinking that we need to call the read method on the product bean from a utility method that's marked NotSupported. But that sounds too much like programmatic tx control. So how do you address this problem? I'm looking for a best practice approach.
Cliff