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
- Server XML datasource: transactional=false
TransactionManagementType=BEAN
Result: 1/2 records persisted. Since there is no transaction management code written, this is expected.- Server XML datasource: transactional=true
TransactionManagementType=CONTAINER
Result: 0/2 records persisted. Since transaction management is enabled 0 records are inserted.- Server XML datasource: transactional=false
TransactionManagementType=CONTAINER
Result: 1/2 records persisted- 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.- 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?
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?