type=page
status=published
title=Container-Managed Transactions
next=transactions005.html
prev=transactions003.html
~~~~~~
= Container-Managed Transactions


[[BNCIJ]]

[[container-managed-transactions]]
Container-Managed Transactions
------------------------------

In an enterprise bean with container-managed transaction demarcation,
the EJB container sets the boundaries of the transactions. You can use
container-managed transactions with any type of enterprise bean: session
or message-driven. Container-managed transactions simplify development
because the enterprise bean code does not explicitly mark the
transaction's boundaries. The code does not include statements that
begin and end the transaction. By default, if no transaction demarcation
is specified, enterprise beans use container-managed transaction
demarcation.

Typically, the container begins a transaction immediately before an
enterprise bean method starts and commits the transaction just before
the method exits. Each method can be associated with a single
transaction. Nested or multiple transactions are not allowed within a
method.

Container-managed transactions do not require all methods to be
associated with transactions. When developing a bean, you can set the
transaction attributes to specify which of the bean's methods are
associated with transactions.

Enterprise beans that use container-managed transaction demarcation must
not use any transaction-management methods that interfere with the
container's transaction demarcation boundaries. Examples of such methods
are the `commit`, `setAutoCommit`, and `rollback` methods of
`java.sql.Connection` or the `commit` and `rollback` methods of
`javax.jms.Session`. If you require control over the transaction
demarcation, you must use application-managed transaction demarcation.

Enterprise beans that use container-managed transaction demarcation also
must not use the `javax.transaction.UserTransaction` interface.

[[BNCIK]]

[[transaction-attributes]]
Transaction Attributes
~~~~~~~~~~~~~~~~~~~~~~

A transaction attribute controls the scope of a transaction.
link:#BNCIL[Figure 54-1] illustrates why controlling the scope is
important. In the diagram, `method-A` begins a transaction and then
invokes `method-B` of `Bean-2`. When `method-B` executes, does it run
within the scope of the transaction started by `method-A`, or does it
execute with a new transaction? The answer depends on the transaction
attribute of `method-B`.

[[BNCIL]]

.*Figure 54-1 Transaction Scope*
image:img/javaeett_dt_050.png[
"A diagram showing a transaction between two beans."]

A transaction attribute can have one of the following values:

* `Required`
* `RequiresNew`
* `Mandatory`
* `NotSupported`
* `Supports`
* `Never`

[[BNCIM]]

[[required-attribute]]
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 is the implicit transaction attribute for all
enterprise bean methods running with container-managed transaction
demarcation. You typically do not set the `Required` attribute unless
you need to override another transaction attribute. Because transaction
attributes are declarative, you can easily change them later.

[[BNCIN]]

[[requiresnew-attribute]]
RequiresNew Attribute
^^^^^^^^^^^^^^^^^^^^^

If the client is running within a transaction and invokes the enterprise
bean's method, the container takes the following steps:

1.  Suspends the client's transaction
2.  Starts a new transaction
3.  Delegates the call to the method
4.  Resumes the client's transaction after the method completes

If the client is not associated with a transaction, the container starts
a new transaction before running the method.

You should use the `RequiresNew` attribute when you want to ensure that
the method always runs within a new transaction.

[[BNCIO]]

[[mandatory-attribute]]
Mandatory 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 throws a
`TransactionRequiredException`.

Use the `Mandatory` attribute if the enterprise bean's method must use
the transaction of the client.

[[BNCIP]]

[[notsupported-attribute]]
NotSupported Attribute
^^^^^^^^^^^^^^^^^^^^^^

If the client is running within a transaction and invokes the enterprise
bean's method, the container suspends the client's transaction before
invoking the method. After the method has completed, the container
resumes the client's transaction.

If the client is not associated with a transaction, the container does
not start a new transaction before running the method.

Use the `NotSupported` attribute for methods that don't need
transactions. Because transactions involve overhead, this attribute may
improve performance.

[[BNCIQ]]

[[supports-attribute]]
Supports 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 does not
start a new transaction before running the method.

Because the transactional behavior of the method may vary, you should
use the `Supports` attribute with caution.

[[BNCIR]]

[[never-attribute]]
Never Attribute
^^^^^^^^^^^^^^^

If the client is running within a transaction and invokes the enterprise
bean's method, the container throws a `RemoteException`. If the client
is not associated with a transaction, the container does not start a new
transaction before running the method.

[[BNCIS]]

[[summary-of-transaction-attributes]]
Summary of Transaction Attributes
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

link:#BNCIT[Table 54-1] summarizes the effects of the transaction
attributes. Both the `T1` and the `T2` transactions are controlled by
the container. A `T1` transaction is associated with the client that
calls a method in the enterprise bean. In most cases, the client is
another enterprise bean. A `T2` transaction is started by the container
just before the method executes.

In the last column of link:#BNCIT[Table 54-1], the word "None" means
that the business method does not execute within a transaction
controlled by the container. However, the database calls in such a
business method might be controlled by the transaction manager of the
database management system.

[[sthref235]][[BNCIT]]


*Table 54-1 Transaction Attributes and Scope*


[width="60%",cols="20%,20%,20%"]
|=======================================================================
|*Transaction Attribute* |*Client's Transaction* |*Business Method's*
Transaction
|`Required` |None |T2

|`Required` |T1 |T1

|`RequiresNew` |None |T2

|`RequiresNew` |T1 |T2

|`Mandatory` |None |Error

|`Mandatory` |T1 |T1

|`NotSupported` |None |None

|`NotSupported` |T1 |None

|`Supports` |None |None

|`Supports` |T1 |T1

|`Never` |None |None

|`Never` |T1 |Error
|=======================================================================


[[BNCIU]]

[[setting-transaction-attributes]]
Setting Transaction Attributes
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

Transaction attributes are specified by decorating the enterprise bean
class or method with a `javax.ejb.TransactionAttribute` annotation and
setting it to one of the `javax.ejb.TransactionAttributeType` constants.

If you decorate the enterprise bean class with `@TransactionAttribute`,
the specified `TransactionAttributeType` is applied to all the business
methods in the class. Decorating a business method with
`@TransactionAttribute` applies the `TransactionAttributeType` only to
that method. If a `@TransactionAttribute` annotation decorates both the
class and the method, the method `TransactionAttributeType` overrides
the class `TransactionAttributeType`.

The `TransactionAttributeType` constants shown in link:#GKCFD[Table
54-2] encapsulate the transaction attributes described earlier in this
section.

[[sthref236]][[GKCFD]]

*Table 54-2 TransactionAttributeType Constants*

[width="34%",cols="100%,",options="header",]
|========================================================
|Transaction Attribute |TransactionAttributeType Constant
|`Required` |`TransactionAttributeType.REQUIRED`
|`RequiresNew` |`TransactionAttributeType.REQUIRES_NEW`
|`Mandatory` |`TransactionAttributeType.MANDATORY`
|`NotSupported` |`TransactionAttributeType.NOT_SUPPORTED`
|`Supports` |`TransactionAttributeType.SUPPORTS`
|`Never` |`TransactionAttributeType.NEVER`
|========================================================


The following code snippet demonstrates how to use the
`@TransactionAttribute` annotation:

[source,oac_no_warn]
----
@TransactionAttribute(NOT_SUPPORTED)
@Stateful
public class TransactionBean implements Transaction {
...
    @TransactionAttribute(REQUIRES_NEW)
    public void firstMethod() {...}

    @TransactionAttribute(REQUIRED)
    public void secondMethod() {...}

    public void thirdMethod() {...}

    public void fourthMethod() {...}
}
----

In this example, the `TransactionBean` class's transaction attribute has
been set to `NotSupported`, `firstMethod` has been set to `RequiresNew`,
and `secondMethod` has been set to `Required`. Because a
`@TransactionAttribute` set on a method overrides the class
`@TransactionAttribute`, calls to `firstMethod` will create a new
transaction, and calls to `secondMethod` will either run in the current
transaction or start a new transaction. Calls to `thirdMethod` or
`fourthMethod` do not take place within a transaction.

[[BNCIV]]

[[rolling-back-a-container-managed-transaction]]
Rolling Back a Container-Managed Transaction
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

There are two ways to roll back a container-managed transaction. First,
if a system exception is thrown, the container will automatically roll
back the transaction. Second, by invoking the `setRollbackOnly` method
of the `EJBContext` interface, the bean method instructs the container
to roll back the transaction. If the bean throws an application
exception, the rollback is not automatic but can be initiated by a call
to `setRollbackOnly`.

[[BNCIW]]

[[synchronizing-a-session-beans-instance-variables]]
Synchronizing a Session Bean's Instance Variables
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

The `SessionSynchronization` interface, which is optional, allows
stateful session bean instances to receive transaction synchronization
notifications. For example, you could synchronize the instance variables
of an enterprise bean with their corresponding values in the database.
The container invokes the `SessionSynchronization` methods
(`afterBegin`, `beforeCompletion`, and `afterCompletion`) at each of the
main stages of a transaction.

The `afterBegin` method informs the instance that a new transaction has
begun. The container invokes `afterBegin` immediately before it invokes
the business method.

The container invokes the `beforeCompletion` method after the business
method has finished but just before the transaction commits. The
`beforeCompletion` method is the last opportunity for the session bean
to roll back the transaction (by calling `setRollbackOnly`).

The `afterCompletion` method indicates that the transaction has
completed. This method has a single `boolean` parameter whose value is
`true` if the transaction was committed and `false` if it was rolled
back.

[[BNCIX]]

[[methods-not-allowed-in-container-managed-transactions]]
Methods Not Allowed in Container-Managed Transactions
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

You should not invoke any method that might interfere with the
transaction boundaries set by the container. The following methods are
prohibited:

* The `commit`, `setAutoCommit`, and `rollback` methods of
`java.sql.Connection`
* The `getUserTransaction` method of `javax.ejb.EJBContext`
* Any method of `javax.transaction.UserTransaction`

You can, however, use these methods to set boundaries in
application-managed transactions.
