Objects: EJB Procedures
When an EJB is called from a web panel, a new LUW is created. It can be managed in two ways:
- By the object (bean) itself
- By the EJB Container where it runs.
An interesting advantage of the second option is that it allows a non GeneXus developer -usually someone with deep knowledge about the EJB Container- to configure the LUWs of this GeneXus EJB procedure.
This feature makes the GeneXus EJBs more independent from the GeneXus Java applications because they can be called by an external client. In addition, their LUWs can be managed in the EJB Container.
In order to set whether to use this feature or not, a new object property called Transaction Type was implemented. Its values are as follows:
Container: The LUW will be managed by the EJB Container. When this value is set, an attribute must be set for the Container. In this case, another property called Transaction Attribute is available to tell the Container how to manage the LUW of this bean.
NOTE: In order to use this value (by the way, it's the default value) the connection to the database must be through a datasourse defined in the J2EE Server (not use the GX connection pool, but the server connection pool). See more information here
Object: The bean behaves as it always did, which means that the object's programmer defines the size of the LUW using the commit and/or rollback commands, as well as the Commit on Exit property.
When the LUW is managed by the EJB Container, the commit commands are ignored. The Container will always execute the commit at the end of the bean execution. But if a rollback exists, the commit won't be done.
That is very important:
- If an EJB procedure or any other procedure called by it has a commit, the Container will ignore it and the commit won't be done.
- If an EJB procedure or any other procedure called by it has a rollback, the Container will set a flag in order to remember at the end (not at this exact moment) of the execution that it doesn't have to do the commit.
When the Container value is set, a new property called Transaction Attribute is available. Its values are as follows: Required, RequiresNew, Supports, Mandatory, NotSupported or Never
Use the Required mode to have your bean always run in a transaction. If a transaction is already running, your bean joins in that transaction. If no transaction is running, the EJB container starts one for you.
Use the RequiresNew attribute to have a new transaction started every time your bean is called. If a transaction is already underway when your bean is called, that transaction is suspended during the bean invocation.
Then, the Container launches a new transaction and delegates the call to the bean. The bean performs its operations and completes them.
Finally, the Container commits or aborts the transaction and resumes the old transaction. Of course, if no transaction is running when your bean is called, there is nothing to suspend or resume.
When a bean is called with Supports, it only runs in a transaction if the client already has one running -it joins that transaction. If the client does not have a transaction, the bean runs with no transaction at all.
Mandatory requires that a transaction must be already running when your bean method is called.
If there is no running transaction, the javax.ejb.TransactionRe-quiredException exception is thrown back to the caller. This other exception is thrown if the client is local: javax.ejb.Transaction-RequiredLocalException.
If you set your bean to use NotSupported, it can't be involved in a transaction.
For example, suppose that we have two enterprise beans, A and B. Bean A begins a transaction and then calls bean B. If bean B is using the NotSupported attribute, the transaction started by A is suspended. When B completes, A's transaction is resumed.
None of B's operations are transactional, such as reads/writes to databases.
The Never transaction attribute means that your bean can't be involved in a transaction.
Besides, if the client calls your bean in a transaction, the Container throws an exception back to the client:
- Remote: java.rmi.RemoteException
- Local: javax.ejb.EJBException