A transaction is a unit of work that changes application state - whether on disk, in memory or in a database - that, once started, is completed entirely, or not at all.
Transactions can be demarcated - started, and ended with a commit or rollback - by the EJB container (like Tomcat), by bean code, or by client code.
The pipeline server scheduler will initiate several threads of execution of these tasks at any given time. Each of the tasks is accessing database and modifying database tables at the application level and the task submission can fail at any level before a final commit on database table updates is called. In this case the pipeline server needs to perform the rollback on the thread's initiated set of changes.
One of the basic questions is what happens if one thread initiates updates, and than performs the rollback at the application level, while the other thread performs a successful commit at the application level. Is there a potential for a deadlock and in what state is the database left?
Container-Managed Transactions (CMT)s are simpler to develop and perform well. Container-managed transactions are supported by all bean types: session, entity, and message-driven. They provide good performance, and simplify development because the enterprise bean code does not include statements that begin and end the transaction.
Each method in a CMT bean can be associated with a single database transaction, but does not have to be. In a container-managed transaction, the EJB container manages the transaction, including start, stop, commit, and rollback. Usually, the container starts a transaction just before a bean method starts, and commits it just before the method exits.
If a system exception is thrown during a transaction, the container will automatically roll back the transaction. You can also explicitly program rollbacks in your bean.
You need to define multiple database transactions with a single method call. With container - managed transactions, a method can only be associated with a single transaction. You can use a bean-managed transaction to define multiple transactions with a single method. However, it is worth avoiding the need for a bean-managed transaction by breaking the method in to multiple methods, each with its own container-managed transaction.
We need to define a single transaction that spans multiple EJB method calls. For example, a stateful session EJB that uses one method to begin a transaction, and another method to commit or roll back a transaction. It is best to avoid this practice, because it requires detailed information about the workings of the EJB object. However, if this scenario is required, we must use bean-managed transaction coordination, and we must coordinate client calls to the respective methods.
The purpose of the transaction pattern is to group a collection of methods so that they either all succeed or they all fail collectively.
One recalls a famous example of transferring funds from one bank account to another. They either need both to succeed or both need to fail. Thus we expect several methods to be fully synchronized and a recovery option should be available. The main players in the pattern are:
/**
* The interface that defines all the methods to control every participant
*/
interface TransactionParticipant {
boolean join(long transactionID);
void commit(long transactionID);
void cancel(long transactionID);
}
/**
* interface that defines the business methods. Methods can throw Exceptions
* as a signal of failure.
*/
interface SpecificParticipant extends TransactionParticipant {
boolean operation1(long transactionID);
boolean operation2(long transactionID);
...
}
/**
* implements all the interface methods and defines what happens if the
* transaction manager decides to cancel() or commit(). It has to keep a
* reference to the original state, to be able to restore when the cancel
* is invoked (Memento pattern is recommended).
*/
public class ConcreteParticipant implements SpecificParticipant {
void cancel();
void commit();
....
}
/**
* Call the join method on the participants and ultimately calls either cancel
* or commit on the participants.
*/
public class TransactionManager {
...
}
We use the transaction as follows: