| Lesson 10 | Session Beans and Transactions |
| Objective | Explain how session beans participate in transactions using SessionSynchronization and EJBContext. |
In Jakarta EE, session beans are often the core components of enterprise applications, encapsulating business logic while working under the control of a transaction manager. Even when a bean does not manage transactions directly, such as when it relies on container-managed transactions, it can still synchronize its internal state and influence transaction outcomes through two mechanisms:
The SessionSynchronization interface allows a session bean to receive notifications about the progress of a transaction in which it participates. This synchronization capability is particularly useful when the bean maintains in-memory data that must be coordinated with persistent storage before the transaction commits.
To use this feature, the bean class implements the SessionSynchronization interface:
import jakarta.ejb.SessionSynchronization;
import jakarta.ejb.Stateful;
@Stateful
public class BankAccountBean implements SessionSynchronization {
// Business methods...
}
The container calls the following methods at specific transaction lifecycle points:
void afterBegin() â Invoked immediately after the transaction begins.void beforeCompletion() â Called just before the transaction is committed, allowing the bean to flush or synchronize in-memory data.void afterCompletion(boolean committed) â Called after the transaction finishes. The committed parameter indicates whether the transaction succeeded (true) or rolled back (false).
While these callbacks do not allow the bean to alter the transaction outcome, they are essential for maintaining consistency between a beanâs transient state and its persistent data. For example, a stateful session bean can use beforeCompletion() to push pending updates to the database just before commit.
The EJBContext interface provides another way for a session bean to interact with the current transaction. It offers methods to programmatically query or influence the transactionâs status:
public interface EJBContext {
boolean getRollbackOnly();
void setRollbackOnly();
// other context methods...
}
These methods give the bean limited control over the transaction:
getRollbackOnly() â Returns true if the transaction is marked for rollback.setRollbackOnly() â Marks the current transaction so that it cannot be committed. The transaction manager will roll it back when it ends.Both methods are valid in container-managed and bean-managed transactions. They are typically used when a bean detects an application-level error that should cause the transaction to fail, such as a validation failure or business rule violation.
A well-designed enterprise bean uses SessionSynchronization to maintain data integrity during a transaction and EJBContext to mark failures that require rollback. Together, they give developers controlled access to transaction events while letting the Jakarta EE container handle complex coordination and recovery.
import jakarta.ejb.EJBContext;
import jakarta.annotation.Resource;
import jakarta.ejb.Stateless;
import jakarta.transaction.Transactional;
@Stateless
@Transactional
public class PaymentService {
@Resource
private EJBContext context;
public void processPayment(double amount) {
try {
// Business logic that might fail
if (amount <= 0) {
throw new IllegalArgumentException("Invalid payment amount");
}
// Continue with persistence or remote calls...
} catch (Exception e) {
context.setRollbackOnly(); // Mark transaction for rollback
throw e;
}
}
}
This pattern ensures that any unexpected exception or validation issue leads to a clean rollback without leaving the database in an inconsistent state.
Session beans participate in transactions even when they do not explicitly manage them. Using SessionSynchronization, beans stay informed about transaction lifecycle events, while EJBContext allows beans to signal rollback conditions. Together, they form the foundation for reliable, state-consistent enterprise applications under Jakarta EE.
The next module introduces stored procedures and JTA integration, showing how transaction boundaries extend across multiple enterprise resources.