Search code examples
jakarta-eeejbejb-3.0websphere-libertytransactional

EJB transaction management


I am trying to understand EJB transaction management. I wrote the below code and deployed in websphere liberty

@Stateless
@TransactionManagement(TransactionManagementType.BEAN)
public class BookRepositoryBean {

  @Resource(lookup = "jdbc/mydb")
  private DataSource dataSource;

  public void create(List<Book> books) {

  try {
    for(Book book: books) {
      Connection con = dataSource.getConnection();
      PreparedStatement stmt = con.preparedStatement("insert into ....");
      stmt.setString(1, ...);
      stmt.executeUpdate();
    }
  } catch(SQLException e) {
    throw new RuntimeException(e.getMessage());
  }
}

My server.xml looks something like below

<dataSource jndiName="jdbc/mydb" transactional="false">
....
</dataSource>

I manually inserted a record in the table which has a primary key constraint and then tried running my code to persist two records where one is a duplicate record and another is a new record.

I tried with different options and observed the following

  1. Server XML datasource: transactional=false
    TransactionManagementType=BEAN
    Result: 1/2 records persisted. Since there is no transaction management code written, this is expected.

  2. Server XML datasource: transactional=true
    TransactionManagementType=CONTAINER
    Result: 0/2 records persisted. Since transaction management is enabled 0 records are inserted.

  3. Server XML datasource: transactional=false
    TransactionManagementType=CONTAINER
    Result: 1/2 records persisted

  4. Server XML datasource: transactional=true
    TransactionManagementType=BEAN
    Result: 1/2 records persisted. I understood that, since I turned off transaction management at code level, 1 record has been persisted.

  5. Server XML datasource: transactional=true
    Removed @Stateless and @TransactionManagement annotations
    Result: 0/2 records persisted.

In case 3, I dont understand why 1 record is inserted. I am assuming container level transaction management will work only when enabled in code and also by enabling at container level. Am i right?

In case 5, I don't understand why 0 records have been persisted when the class is not an EJB. I always assumed that transaction management is only available with EJBs. This test has proved me wrong. Now I don't understand why should one choose EJB over a regular java class.

Can anyone please explain?


Solution

  • Regarding #5, by removing the annotations and having it be a normal java class, it runs under the transaction and context of the invoker. Is the invoker another EJB with container managed transactions?