Need help with misunderstanding about CMT

Discussions

General J2EE: Need help with misunderstanding about CMT

  1. Need help with misunderstanding about CMT (5 messages)

    Hello,

    I believe I have a basic misunderstanding about Container Managed Transactions and I really need some help clearing it up. From everything that I read, if you are using CMT the only transaction-related methods your code should ever call are setRollbackOnly()/getRollbackOnly(). You never call commit(), you never call rollback(), and you certainly never do anything like obtain a connection from a DriverManager, correct?

    So here's what I don't understand. Let's say I want my CMT bean to uses two different DAOs (DataAccessObjects) for reading information from a database. You're not supposed to pass the DAO a connection, right? But if your DAO does access a database, it's going to need a connection, right? Where does it get one? And since I want anything the DAO does to run in the same transaction that my bean method is already running in, how do I ensure that? Do I need to make sure my DAOs do not call commit/rollback? Seems like I would.

    The DAOs that I've looked at get their connections by doing a JNDI lookup on a datasource. Fine. But what is the relationship between this connection object and the transaction my bean is already running in? And if each DAO gets its own connection this way, what is the relationship between them and the transaction my bean is running in? Is the container aware that my DAOs have requested connections so it is passing them each the same connection object to ensure that what each DAO does is part of the same transaction?

    As you can see, there's something fundamental missing from my understanding. Any light you can shed would be appreciated!

    -john
  2. Hi John,

    well, if you're going to use CMP (Container Managed Persistence), you won't need your DAOs anymore. CMP entity beans are declaratively configured through XML deployment descriptors... You provide the deployment descriptors, CMP beans take care of O-R mapping and transaction management by themselves: that's how things work when you choose CMP.

    There are many books on EJB that will show you how to use CMP entity beans. Some are available here on TSS. You can also take a look at the J2EE Tutorial:

    http://java.sun.com/j2ee/1.4/docs/tutorial/doc/index.html

    Hope this helps,

    Cristina
  3. I appreciate your response - but I'm not interested in using CMP. I want to understand, specifically, how CMT works. Here's a simpler example of what I need to understand:

    Let's say we are using a CMT stateless session bean. The bean needs to create statements and execute them against a database. In order to do this, that means the bean will need access to a connection. What's the proper way to obtain access to a connection object so that my bean properly follows the conventions of a CMT bean?

    The examples that I've seen all get their connections from a datasource - but I want to know how obtaining a connection in this manner creates a "relationship" between that connection object and the container so that the container can do the commit/rollback for my bean. Does that make sense?

    Thanks!
  4. The examples that I've seen all get their connections from a datasource - but I want to know how obtaining a connection in this manner creates a "relationship" between that connection object and the container so that the container can do the commit/rollback for my bean. Does that make sense?

    Yes, it does - and you've already answered your question here:
    Is the container aware that my DAOs have requested connections so it is passing them each the same connection object to ensure that what each DAO does is part of the same transaction?

    That's exactly what happens. Remember that according to the EJB rules your DAOs are all running in the same thread. All container implementations I've seen simply store a reference to the connection (actually it's usually some kind of proxy object, not a plain JDBC connection) in thread local storage. The container simply looks for that connection in the TLS for the thread that it is currently executing, so the DAOs in one thread always get the same connection. Good question, anyways.

    Best regards,
    Stefan
  5. Thanks for you response - but there's still something here I don't understand.

    There are numerous ways to get connections - you can get one from a DriverManager - you can do a JNDI lookup on a datasource and get a connection from that. How does the container "intercept" my attempts to get a connection object so that the container can pass me the "right" connection? When I do a JNDI lookup for a datasource and ask it for a connection, I'm not really asking the *container* for a connection - I'm asking the dataSource. So the container must have its "fingers" inside that datasource somehow. Likewise with a DriverManager - though I'm guessing it's illegal to obtain a connection object from a DriverManager if you want to do CMT, correvct? Otherwise the container would have to intercept attempts to get connections from a DriverManager and I'm not sure how I see that happening.

    Your thoughts?
  6. Hi John,

    as a matter of fact, I didn't understand your first question... Still, after reading this one, it looks like you've been talking about *transaction attributes* all the time.

    From the J2EE Tutorial (Container-Managed Transactions):

    "When deploying a bean, you specify which of the bean's methods are associated with transactions by setting the transaction attributes... A transaction attribute controls the scope of a transaction... A transaction attribute can have one of the following values: Required, RequiresNew, Mandatory, NotSupported, Supports, Never."

    Let's take a closer look at the *Required* attribute:

    "If the client is running within a transaction and invokes the enterprise bean's method, the method executes within the client's transaction. If the client is not associated with a transaction, the container starts a new transaction before running the method.

    The Required attribute will work for most transactions. Therefore, you may want to use it as a default, at least in the early phases of development. Because transaction attributes are declarative, you can easily change them later."

    Please see:

    http://java.sun.com/j2ee/1.4/docs/tutorial/doc/Transaction3.html

    Transactional behavior doesn't depend on the connection (if you're using CMT, the container will be keeping track of connections anyway). Actually, the container knows what to do by looking at the value of transaction attributes.

    Hope this helps this time :-),

    Cristina