0

I am new both to EJB and Bean Managed Transactions. After scrapping the Internet, I found that I could write a EJ session Bean which does transactions the "bean-managed way", like this:

@TransactionManagement(value=TransactionManagementType.BEAN)
@Stateless
public class OperationBean {
    @Resource
    private UserTransaction userTransaction;
    public void operation() {
        try{
            userTransaction.begin();
            Op1();
            Op2();
            Op3();
            userTransaction.commit();
        } catch(Exception e){
            userTransaction.rollback();
        }
    }
}

However, I do not understand what happens if an exception is thrown by Op3(). How are Op1() and Op2() undone?

Another question is how do I bind this to JSF? I need to write a form in JSF that sends its data to the server and the OperationBean does 3 operations based on the received data. These operations do involve database operations(3 updates) and do not make sense individually.

Thanks!

Roman C
  • 49,761
  • 33
  • 66
  • 176
MciprianM
  • 513
  • 1
  • 7
  • 18

1 Answers1

5

When you call userTransaction.begin(), simply saying JTA begins transaction on database level. Now all the data modifications you perform are done inside transaction. If everything is OK, execution comes to userTransaction.commit() and database fixes transaction. If something's going wrong, you call userTransaction.rollback() in catch block and database drops all the modifications you do after begin().

In two words it is difficult to explain how database transactions work, but basically database isolates all changes during transaction from other clients until commit() or rollback() is called and prevents external updates of data you are working with.

In JSF you can create @ManagedBean and inject your OperationBean into it with @EJB annotation. You should get something like this

@ManagedBean
public class Operation {
    @EJB
    private OperationBean operationBean;

    public void doOperation() {
        operationBean.operation();
    }
}

and in your view

<h:form>
    <h:commandButton action="#{operation.doOperation}" value="Do Operation"/>
</h:form>

So you're doing it right. Assuming you really need bean managed transactions, not container managed.

GKlimov
  • 409
  • 2
  • 7
  • "JTA begins transaction on database level" - how does it know which database am I using in Op1(), Op2() and Op3(). Do these methods need to contain something to notify JTA what database am I modifying? – MciprianM Jun 25 '13 at 14:12
  • You want to make changes in multiple databases? This approach works in case of single DB. Multiple DBs bring you to distributed transactions, so you should look for `XAResource` usage examples. – GKlimov Jun 25 '13 at 14:23
  • I am using a single database. But do I need to use it in a given way or can I just use java.sql.Connection and java.sql.PreparedStatement classes for updating the DB? – MciprianM Jun 25 '13 at 14:33
  • If you use EJB, there's no reason to work without JTA. So inject `@PersistenceContext private EntityManager em;` and make calls to DB with `em.createQuery()` (for JPA queries) or `em.createNativeQuery()` (for SQL). For updates, create JPA mapping and use `em.merge(obj)`. – GKlimov Jun 25 '13 at 14:38
  • This is a poor answer. The question does not indicate that any database is used at all, and your comments here do not further help your answer. Is this to indicate that all JTA must and can only be used for databases? I am still trying to figure out how to roll back (in the example above) op1, and op2 if no database is involved and this answer does not answer that at all. This answer doesn't even answer how the database does get involved implicitly even if the OP does mean to use a database. – searchengine27 Dec 13 '22 at 23:28